要搞懂JS繼承,我們首先要理解原型鏈:每一個實體物件都有一個__proto__屬性(隱式原型),在js內部用來查找原型鏈;每一個建構式都有prototype屬性(顯示原型),用來顯示修改物件的原型,實體.__proto__=建構式.prototype=原型,原型鏈的特點就是:通過實體.__proto__查找原型上的屬性,從子類一直向上查找物件原型的屬性,繼而形成一個查找鏈即原型鏈,
1.原型鏈繼承
我們使用原型繼承時,主要利用sub.prototype=new super,這樣連通了子類-子類原型-父類,
1 //父類,帶屬性 2 function Super(){ 3 this.flag = true; 4 } 5 //為了提高復用性,方法系結在父類原型屬性上 6 Super.prototype.getFlag = function(){ 7 return this.flag; 8 } 9 //來個子類 10 function Sub(){ 11 this.subFlag = false; 12 } 13 //實作繼承 14 Sub.prototype = new Super; 15 //給子類添加子類特有的方法,注意順序要在繼承之后 16 Sub.prototype.getSubFlag = function(){ 17 return this.subFlag; 18 } 19 //構造實體 20 var es5 = new Sub;
缺點:建構式原型上的屬性在所有該建構式構造的實體上是共享的,即屬性沒有私有化,原型上屬性的改變會作用到所有的實體上,
2.建構式繼承
在構造子類建構式時內部使用call或apply來呼叫父類的建構式
function Super(){ this.flag = true; } function Sub(){ Super.call(this) //如果父類可以需要接收引數,這里也可以直接傳遞 } var obj = new Sub(); obj.flag = flase; var obj_2 = new Sub(); console.log(obj.flag) //依然是true,不會相互影響
優缺點:實作了屬性的私有化,但是子類無法訪問父類原型上的屬性,
3.組合繼承
利用建構式和原型鏈的方法,可以比較完美的實作繼承
function Super(){ this.flag = true; } Super.prototype.getFlag = function(){ return this.flag; //繼承方法 } function Sub(){ this.subFlag = flase Super.call(this) //繼承屬性 } Sub.prototype = new Super; var obj = new Sub(); Sub.prototype.constructor = Sub; Super.prototype.getSubFlag = function(){ return this.flag; }
注:
這里還有個小問題,Sub.prototype = new Super; 會導致Sub.prototype的constructor指向Super;然而constructor的定義是要指向原型屬性對應的建構式的,Sub.prototype是Sub建構式的原型,所以應該添加一句糾正:Sub.prototype.constructor = Sub;
4.寄生繼承
即將sub.prototype=new super改為sub.prototype=Object.creat(supper.prototype),避免了組合繼承中建構式呼叫了兩次的弊端,
轉:https://blog.csdn.net/qq_25461519/article/details/81060130
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/174708.html
標籤:JavaScript
