我們這裡這裡主要討論js中的主要繼承方式,包括建構函式繼承,原型繼承,組合式繼承(原型繼承和建構函式繼承的組合),寄生繼承(原型繼承的變形)和寄生組合式繼承(寄生繼承和建構函式繼承的組合)。
建構函式繼承
function supertype(name)
supertype.prototype.sayname = function()
function subtype(name, age)
var sub1 = new subtype('zyp1', 18)
sub1.colors.push('yellow')
console.log('sub1', sub1)
var sub2 = new subtype('zyp2', 18)
console.log('sub2', sub2)
得到的sub1和sub2的結果如下:
可以看到,建構函式繼承就是在子類中呼叫父類的方法,從而實現繼承父類的例項屬性,它有2個優點:1.每個子類例項繼承的父類的例項屬性在堆空間中是占用不同記憶體的,因此修改乙個子類例項繼承自父類的例項屬性並不會對另乙個子類的例項造成任何影響(這裡的colors屬性);2.可以通過在子類建構函式中呼叫父類建構函式時向其傳遞引數(這裡的name屬性)。但是這裡也有乙個很大的問題:子類不可以繼承父類原型上的原型方法。那麼就談不上方法復用了,因此一般不會單獨使用建構函式繼承。
2. 原型繼承
function supertype()
supertype.prototype.sayname = function()
function subtype(name, age)
subtype.prototype = new supertype()
subtype.prototype.sayhi = function()
var sub1 = new subtype('zyp1', 18)
sub1.colors.push('yellow')
console.log('sub1', sub1)
sub1.sayname()
var sub2 = new subtype('zyp2', 18)
console.log('sub2', sub2)
sub2.sayname()
得到的sub1和sub2結果如下:
可以看到,原型繼承就是將父類的例項賦給子類的原型物件,這樣父類的例項屬性就變成了子類的原型屬性,同時子類也可以繼承父類的原型方法和原型屬性(如果有的話)。但是這種方法同樣有乙個重大缺點,就是這種方式繼承得到的父類的例項屬性如果是引用型別的話,子類例項對其進行的操作是會相互影響的(如這裡的colors),因為我們知道物件的原型屬性是共用的。因此一般情況下也不會單獨使用原型繼承。
3. 組合式繼承
function supertype()
supertype.prototype.sayname = function()
function subtype(name, age)
subtype.prototype = new supertype()
subtype.prototype.constructor = subtype //原型繼承會將子類原型上的constructor屬性丟失,這裡加上
subtype.prototype.sayhi = function()
var sub1 = new subtype('zyp1', 18)
sub1.colors.push('yellow')
console.log('sub1', sub1)
sub1.sayname()
var sub2 = new subtype('zyp2', 18)
console.log('sub2', sub2)
sub2.sayname()
得到的sub1和sub2結果如下:
可以看到,組合式繼承就是將建構函式繼承和原型繼承進行了組合,建構函式繼承實現對父類例項屬性的繼承,原型繼承實現對原型方法和原型屬性的繼承。但是這裡也有乙個缺點就是父類建構函式被呼叫了2次,產生的結果就是父類的例項屬性同時存在於子類例項的例項屬性和原型屬性中。
4. 寄生式繼承
function object(o)
f.prototype = o
return new f()
}
var obj =
function createanother(o)
return clone
}var clone1 = createanother(obj)
clone1.color.push('yellow')
console.log('clone1',clone1)
var clone2 = createanother(obj)
console.log('clone2',clone2)
得到的clone1和clone2的結果如下:
可以看到,單純的寄生式繼承實際上就是用object函式封裝了子類繼承父類的過程,其實實際上就是實現了原型繼承,那麼顯然跟原型繼承一樣,就是這種方式繼承得到的父類的例項屬性如果是引用型別的話,子類例項對其進行的操作是會相互影響的(如這裡的color)。
5. 寄生組合式繼承
function object(o)
f.prototype = o
return new f()
}
function supertype(name)
supertype.prototype.sayname = function()
function inheritprototype(subtype, supertype)
function subtype(name, age)
inheritprototype(subtype, supertype);
subtype.prototype.sayage = function()
var sub1 = new subtype('zyp1', 18)
sub1.colors.push('yellow')
console.log('sub1', sub1)
var sub2 = new subtype('zyp2', 18)
console.log('sub2', sub2)
得到的sub1和sub2的結果如下:
寄生組合式繼承通過建構函式實現對例項屬性的繼承,通過寄生繼承的方式來實現對原型方法和原型屬性的繼承,該方法規避了組合繼承方式中呼叫父類建構函式兩次造成的問題,因此這種方式得到的子類例項中僅出現一次父類的例項屬性,目前被認為是最佳實踐。
談談JS繼承
function parent value parent.prototype.getparentvalue function function child child.prototype newparent var child newchild child.getparentvalue parent...
談談Js繼承的那些事兒
1.使用物件冒充實現繼承 實現原理 讓父類的建構函式成為子類的方法,然後呼叫該子類的方法,以實現物件的繼承。var people function name,age people.prototype.showpinfo function var men function men.prototype....
js中的繼承
繼承有兩種方式 介面繼承和實現繼承。介面繼承只繼承方法簽名,而實現繼承則繼承實際的方法。由於函式沒有簽名,在ecmascript中無法實現介面繼承。ecmascript只支援實現繼承,而且實現繼承主要依靠原型鏈來實現。下面介紹幾種js的繼承 原型鏈繼承實現的本質是重寫原型物件,代之以乙個新型別的例項...