構造函數數組
基本概念瀏覽器
繼承方式安全
<script> function Person(name, age) { this.name = name; this.age = age; } //不只擁有構造函數中的屬性,還擁有原型中建立出來的屬性 Person.prototype.gender = 'male'; var p = new Person('qx', 18); console.log(p.name);//qx console.log(p.age);//18 console.log(p.gender);//male </script>
<script> var o = {} var obj = { name: "張三", age: 18, sayHello: function () { console.log("Hello world"); } } //混入式繼承 for (var k in obj) { o[k] = obj[k]; } console.log(o); </script>
一、最先的原理函數
<script> //經過替換原型,使得被建立出來對象也擁有傳入對象的屬性 function jicheng(obj) { var o = {}; o.__proto__ = obj; return o; } var o = jicheng({name: "張三"}); console.log(o); </script>
二、create方法this
<script> var o = { name: "週三" }; var obj = Object.create(o); console.log(obj.name); </script>
三、create方法存在兼容性問題spa
<script> var obj = { name:"週三" }; //檢測瀏覽器的能力,若是沒有Object.create方法就給他添加一個(不推薦使用) if(Object.create){ var o = Object.create(obj); }else{ Object.create = function () { function F() { } F.prototype = obj; var o = new F(); } var o = Object.create(obj); } </script>
<script> //本身定義個函數 function create(obj) { if (Object.create) { return Object.create(obj); } else { function F() { } F.prototype = obj; return new F(); } } </script>
原型對象prototype
<script> function Person(name, age) { this.name = name; this.age = age; } Person.prototype.say=function () { console.log('chi'); } var p=new Person('wx',18); p.say();//chi </script>
<script> function Person(name, age) { this.name = name; this.age = age; } Person.prototype={ say:function () { console.log('chi'); }, play:function () { console.log('wan'); } }; var p=new Person('wx',18); p.say();//chi p.play();//wan </script>
<script> function Person(name, age) { this.name = name; this.age = age; } console.dir(Person.prototype); Person.prototype = { say: function () { console.log('chi'); }, play: function () { console.log('wan'); } }; Person.prototype.constructor = Person; console.dir(Person.prototype); </script>
原型繼承3d
將animal這個對象賦值給Person.prototype,與上面的經過字面量{}道理是同樣的,畢竟animal也是一個對象,裏面的屬性也是被{}包裹的調試
<script> function Animal() { this.eat = 'chifan'; } var animal = new Animal(); function Person() { this.read = 'dushu'; } var p1 = new Person(); //person顯示是具備animal的屬性,畢竟人也是動物,具體方法是讓person的原型被替換成animal //替換後,經過person構造函數建立出來的對象,不只具備person的屬性,還具備animal的屬性 Person.prototype = animal;//Person.prototype = new Animal()這樣也行 var p2 = new Person(); console.log(p1); console.log(p2); </script>
輸出結果:code
結果分析:
複雜原型繼承
<script> function Yuanzi() { this.des = '進化'; } function Animal() { this.skill = '捕獵'; } function Human() { this.say = '說話'; } Animal.prototype = new Yuanzi(); Animal.prototype.constructor = Animal; Human.prototype = new Animal(); Human.prototype.constructor = Human; var h = new Human(); console.log(h); </script>
打印對象h:
構造器的做用
原型鏈基本概念
一、每一個構造函數都有原型對象
二、每一個對象都會有構造函數
三、每一個構造函數的原型都是一個對象
四、那麼這個原型對象也會有構造函數
五、那麼這個原型對象的構造函數也會有原型對象
六、這樣就會造成一個鏈式的結構,稱爲原型鏈
七、經過修改原型鏈結構實現的繼承,就叫作原型繼承
八、三角關係到成立的必要性之一是 實例化對象p原型的原型與Object構造函數都是指向同一個對象(在內存中的內容與地址都是同樣的)
consolo.log (p.__proto__.__proto__===Object.prototype)//true
屬性搜索基本原則
原型對象的替換
上面負責原型繼承的模式是進行的原型的替換,這樣雖然方便了,可是也是有問題的
(1)給原型對象替換賦值,原型對象就會失去constructor屬性
<script> function Person(name, age) { this.name = name; this.age = age; } var p = new Person('qx', 18); console.log(Person.prototype); Person.prototype = { say: function () { console.log(this.name); } }; console.log(Person.prototype); </script>
(2)固然即便替換了原型對象,可是實例化後的對象依然具備constructor屬性,而這個屬性屬於對象的原型對象的原型對象,從上圖能夠看出,以及下圖也看出,替換先後打印的結果是不同的。替換後,訪問的是對象的原型對象的原型的構造函數
<script> function Person(name, age) { this.name = name; this.age = age; } var p = new Person('qx', 18); console.log(Person.prototype.constructor); Person.prototype = { say: function () { console.log(this.name); } }; console.log(Person.prototype.constructor); </script>
(3)對原型對象進行替換,其實能夠看做是將一個對象賦值給了一個普通對象,相似var a={},咱們打印a,consolo.dir(a),結果是a並無構造函數的屬性
(4)解決辦法就是,替換了原型對象,必須在替換的對象上面加上constructor屬性,而且賦值指向的是自身構造函數,和上面的複雜原型繼承是同樣的
<script> function Person() { } Person.prototype = { constructor: Person; } </script>
擴展內置對象
<script> function MyArray() { // this.name = '我是一個數組'; } MyArray.prototype = new Array(); var arr1 = new MyArray(); arr1.push(4) console.log(arr1); MyArray.prototype.say = function () { console.log('添加一個說的方法'); } var arr2=new MyArray(); arr2.say(); </script>