聊聊JavaScript如何實(shí)現(xiàn)繼承及特點(diǎn)
“繼承”是面向?qū)ο缶幊汤锩娼?jīng)常提及到的概念,它的目的是實(shí)現(xiàn)代碼復(fù)用。JavaScript并沒(méi)有“類”的概念,那么,它如何實(shí)現(xiàn)繼承呢?
(ES6有關(guān)鍵字class和extend,繼承的語(yǔ)法與Java等面向?qū)ο笳Z(yǔ)言類似,但是,ES6 class,只是JavaScript原型繼承的語(yǔ)法糖而已)
1. 類式繼承
關(guān)鍵點(diǎn):通過(guò)構(gòu)造函數(shù)實(shí)現(xiàn)繼承。
父類:
function Parent(name) {
this.name = name || "parent";
}
Parent.prototype.say = function() {
return this.name;
}
子類:
function Child() {}
(1) 父類對(duì)象繼承
Child.prototype = new Parent("child");
var child = new Child();
child.say(); // "child"
特點(diǎn):使用這種繼承模式,子類不僅僅會(huì)繼承父類原型上的方法/屬性,還會(huì)繼承父類自身的屬性。
這種模式的缺點(diǎn)是,在初始化父類對(duì)象指向給子類原型時(shí),并不確定父類構(gòu)造函數(shù)的初始化參數(shù)(Child.prototype = new Parent("child");),而且,往往這些參數(shù)并不是子類需要的。
(2) 借用構(gòu)造函數(shù)
改造子類:
function Child(){
Parent.apply(this, arguments);
}
特點(diǎn):使用這種繼承模式,子類只會(huì)繼承父類自身的屬性。
缺點(diǎn)很明顯,它無(wú)法從原型鏈中繼承任何方法/屬性。
(3) 共享原型
Child.prototype = Parent.prototype;
這種方式的缺點(diǎn)是,子類原型和父類原型共享一個(gè)對(duì)象,那么,子類如果修改原型,必然會(huì)影響父類。
(4) 臨時(shí)構(gòu)造函數(shù)
function inherit(Child, Parent) {
var F = function(){};
F.prototype = Parent.prototype;
Child.prototype = new F();
}
特點(diǎn):利用一個(gè)空函數(shù)F()充當(dāng)子類和父類之間的代理,既可以實(shí)現(xiàn)父類原型方法/屬性的繼承,又可以在子類原型上繼續(xù)擴(kuò)展方法/屬性。
一般,我們可以利用ES5提供的新方法Object.create()來(lái)實(shí)現(xiàn)此類繼承。
Child.prototype = Object.create(Parent.prototype);
2. 通過(guò)復(fù)制屬性實(shí)現(xiàn)繼承
復(fù)制屬性分為淺拷貝和深拷貝。
淺拷貝不會(huì)復(fù)制對(duì)象類型,只會(huì)簡(jiǎn)單的將對(duì)象引用指向子類,代碼如下:
function extend(parent, child) {
var key;
for(key in parent) {
if (parent.hasOwnProperty(key)){
child[key] = parent[key];
}
}
return child;
}
深拷貝會(huì)做深度復(fù)制,如果某個(gè)屬性為對(duì)象類型,那么,它會(huì)復(fù)制出該對(duì)象的屬性,再拷貝給子類。代碼如下:
function extendDeep(parent, child) {
var key;
for(key in parent) {
if (parent.hasOwnProperty(key)){
if (typeof parent[key] === 'object') {
child[key] = (parent[key].toString() === "[object Array]")? []:{};
extendDeep(parent[key], child[key]);
} else {
child[key] = parent[key];
}
}
}
return child;
}
3. "借用方法"模式復(fù)用父類函數(shù)
如果不想實(shí)現(xiàn)父子之間的完全繼承,僅僅期望子類實(shí)現(xiàn)父類中一個(gè)或多個(gè)方法,那么可以利用apply, call, bind來(lái)調(diào)用父類函數(shù),實(shí)現(xiàn)復(fù)用。
代碼如下:
parent.say.call(child, "hello, child!");
小結(jié)
推薦采用“臨時(shí)構(gòu)造函數(shù)”模式實(shí)現(xiàn)繼承。以上所述是小編給大家介紹的JavaScript如何實(shí)現(xiàn)繼承,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
Javascript es7中比較實(shí)用的兩個(gè)方法示例
這篇文章主要給大家分享了關(guān)于Javascript es7中比較實(shí)用的兩個(gè)方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-07-07
用apply讓javascript函數(shù)僅執(zhí)行一次的代碼
有時(shí)候我們只想要讓某些腳步函數(shù)執(zhí)行一次就算完成任務(wù)了。如何實(shí)現(xiàn)這種功能呢?簡(jiǎn)單模仿下面這段就可以輕松搞定了2010-06-06
js監(jiān)聽(tīng)input輸入框值的實(shí)時(shí)變化實(shí)例
下面小編就為大家?guī)?lái)一篇js監(jiān)聽(tīng)input輸入框值的實(shí)時(shí)變化實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-01-01
Javascript(es2016) import和require用法和區(qū)別詳解
本篇文章主要介紹了Javascript(es2016) import和require用法和區(qū)別詳解,具有一定的參考價(jià)值,有興趣的可以了解下2017-08-08
詳解JavaScript原生封裝ajax請(qǐng)求和Jquery中的ajax請(qǐng)求
在本篇文章中我們總結(jié)了關(guān)于JavaScript原生封裝ajax請(qǐng)求和Jquery中的ajax請(qǐng)求的知識(shí)點(diǎn)內(nèi)容,需要的朋友們學(xué)習(xí)參考下。2019-02-02
前端頁(yè)面在移動(dòng)設(shè)備上顯示不正常的原因及解決方案
當(dāng)頁(yè)面在移動(dòng)設(shè)備上顯示不正常時(shí),通常是由于布局、樣式或響應(yīng)式設(shè)計(jì)設(shè)置不當(dāng)所引起的,移動(dòng)設(shè)備的屏幕尺寸、分辨率和交互方式與桌面設(shè)備有很大的不同,本文將詳細(xì)介紹常見(jiàn)的導(dǎo)致頁(yè)面在移動(dòng)設(shè)備上顯示不正常的原因,以及如何解決這些問(wèn)題,需要的朋友可以參考下2024-09-09
JavaScript下一版本標(biāo)準(zhǔn)ES6的Set集合使用詳解
ES6:全稱ECMAScript 6.0,是JavaScript語(yǔ)言的國(guó)際標(biāo)準(zhǔn),JavaScript是ECMAScript的實(shí)現(xiàn)。今天我們就來(lái)學(xué)習(xí)一下ES6的Set集合的使用2023-02-02
js實(shí)現(xiàn)圓形顯示鼠標(biāo)單擊位置
這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)圓形顯示鼠標(biāo)單擊位置,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-02-02

