function A(){ this.a='a'; this.arr=[1,2]; } A.prototype.funA=function(){ console.log("我是A的方法"); } function B(){ this.b='b'; } B.prototype.funB=function(){ console.log("我是B的方法"); } B.prototype=new A(); var b1=new B();
因爲A的實例可以訪問A.prototype
,因此咱們能夠設置B.prototype
指向A的實例。因此B的實例能夠訪問A的實例以及A.prototype
,實現繼承app
1.因爲對象類型的賦值是引用賦值,若是父類A實例化過程當中有引用類型,那麼子類B的實例的這個屬性都指向同一內存空間。函數
function A(){ this.a='a'; this.arr=[1,2]; } A.prototype.funA=function(){ console.log("我是A的方法"); } function B(){ this.b='b'; } B.prototype.funB=function(){ console.log("我是B的方法"); } B.prototype=new A(); var b1=new B(); var b2=new B(); b1.arr.push(3); console.log(b1.arr); // [1, 2, 3] console.log(b2.arr); // [1, 2, 3]
2.若是父類的實例須要傳入一些參數,那麼兩個子類實例初始化時某一屬性值相同this
function A(year){ this.year=year; } function B(){ this.b='b'; } B.prototype=new A(18); var b1=new B(); var b2=new B(); console.log(b1.color); // 18 console.log(b2.color); // 18
3.B.prototype
中constructor指向不正確,由於B.prototype
指向了一個A的實例,因此本應指向B的constructor指向了Aprototype
function A(year){ this.year=year; } function B(){ this.b='b'; } B.prototype=new A(18); var b1=new B(); b1.constructor===A // true
function A(color){ this.a='a'; this.arr=[1,2]; this.color=color; } A.prototype.funA=function(){ console.log("我是A的方法"); } function B(color){ A.call(this,color); } B.prototype.funB=function(){ console.log("我是B的方法"); } var b1=new B("red"); console.log(b1) // {a: "a", arr: Array(2), color: "red"}
解決了引用賦值問題,也能夠自定義一些屬性了,constructor也指向B了,即解決了類式繼承的第一個、第二個問題以及第三個問題code
很明顯,B除了調用了A這個函數外並無和A扯上什麼關係,原型鏈是不通的(沒法訪問到應該做爲父類的A的prototype屬性),我甚至並不以爲這是一種繼承方式,但它爲下面兩種方法奠基了基礎對象
b1.__proto__===B.prototype // true b1.__proto__.__proto__===Object.prototype // true
說白了,就是將上述兩種方法的長處組合到一塊兒,利用原型鏈實現原型屬性和方法的繼承,經過借用構造函數實現對實例屬性的繼承繼承
function A(color){ this.a='a'; this.arr=[1,2]; this.color=color; } A.prototype.funA=function(){ console.log("我是A的方法"); } function B(color,age){ // 經過借用構造函數實現對實例屬性的繼承 A.apply(this,[color]); this.age=age; } // 利用原型鏈實現原型屬性和方法的繼承 B.prototype=new A(); B.prototype.constructor=B; var b1=new B('red',18);
既經過在原型上定義方法實現了函數複用,又可以保證每一個實例都有它本身的屬性內存
調用了兩次父類的構造函數原型鏈
function A(color){ this.a='a'; this.arr=[1,2]; this.color=color; } A.prototype.funA=function(){ console.log("我是A的方法"); } function B(color,age){ A.apply(this,[color]); this.age=age; } B.prototype=Object.create(A.prototype); B.prototype.constructor=B; var b1=new B('red',18);
只需訪問一次父類的構造函數,避免了在子類的prototype上建立沒必要要、多餘的屬性原型