JS?的繼承方式與使用場(chǎng)景對(duì)比分析
在 JavaScript 中,繼承的實(shí)現(xiàn)方式主要有以下幾種,每種方式適用于不同的場(chǎng)景:
一、原型鏈繼承
實(shí)現(xiàn)方式:
function Parent() { this.name = 'Parent'; } Parent.prototype.say = function() { return this.name; }; function Child() {} Child.prototype = new Parent(); // 原型繼承關(guān)鍵 const child = new Child(); child.say(); // 輸出 "Parent"
特點(diǎn):
- 子類實(shí)例通過原型鏈訪問父類屬性和方法
- 問題:父類的引用類型屬性會(huì)被所有子類實(shí)例共享
場(chǎng)景:
- 簡(jiǎn)單繼承結(jié)構(gòu),無引用類型共享問題需求的場(chǎng)景
- 老項(xiàng)目快速實(shí)現(xiàn)繼承(現(xiàn)代開發(fā)不推薦優(yōu)先使用)
二、構(gòu)造函數(shù)繼承
實(shí)現(xiàn)方式:
function Parent(name) { this.name = name; } function Child(name) { Parent.call(this, name); // 構(gòu)造函數(shù)繼承關(guān)鍵 } const child = new Child('Child'); child.name; // 輸出 "Child"
特點(diǎn):
- 將父類屬性復(fù)制到子類實(shí)例
- 優(yōu)點(diǎn):解決引用屬性共享問題
- 缺陷:無法繼承父類原型上的方法
場(chǎng)景:
- 需要 實(shí)例屬性獨(dú)立性的場(chǎng)景(如每個(gè)對(duì)象需要獨(dú)立狀態(tài))
- 不支持子類復(fù)用父類原型方法(若無需復(fù)用則合適)
三、組合繼承(經(jīng)典繼承)
實(shí)現(xiàn)方式:
function Parent(name) { this.name = name; } Parent.prototype.say = function() { return this.name }; function Child(name) { Parent.call(this, name); // 第1次調(diào)用父類構(gòu)造函數(shù) } Child.prototype = new Parent(); // 第2次調(diào)用父類構(gòu)造函數(shù)(問題根源) Child.prototype.constructor = Child; const child = new Child('Child'); child.say(); // 輸出 "Child"
特點(diǎn):
- 結(jié)合原型鏈繼承(方法繼承)和構(gòu)造函數(shù)繼承(屬性繼承)
- 缺陷:父類構(gòu)造函數(shù)被調(diào)用兩次,子類原型中存在冗余屬性
場(chǎng)景:
- 傳統(tǒng)項(xiàng)目的常規(guī)繼承需求(ES6 出現(xiàn)前的常見方案)
- 需要同時(shí)滿足方法復(fù)用和實(shí)例屬性獨(dú)立的場(chǎng)景
四、原型式繼承
實(shí)現(xiàn)方式:
const parent = { name: 'Parent', friends: ['Alice'] }; const child = Object.create(parent); // 核心API child.name = 'Child'; child.friends.push('Bob'); // friends被所有基于parent創(chuàng)建的對(duì)象共享
特點(diǎn):
- 類似于對(duì)象淺拷貝
- 問題:引用類型屬性共享(與原型鏈相同)
場(chǎng)景:
- 簡(jiǎn)單對(duì)象繼承需求(無構(gòu)造函數(shù)存在的場(chǎng)景)
- 原型鏈的極簡(jiǎn)替代方案(如舊環(huán)境無
Object.create
時(shí)的polyfill
)
五、寄生式繼承
實(shí)現(xiàn)方式:
function createChild(parent) { const obj = Object.create(parent); obj.sayHi = () => 'Hi'; // 添加額外方法 return obj; } const child = createChild({ name: 'Parent' });
特點(diǎn):
- 工廠模式增強(qiáng)對(duì)象
- 缺陷:方法無法復(fù)用,類似構(gòu)造函數(shù)問題
場(chǎng)景:
- 需要給對(duì)象快速擴(kuò)展額外方法的場(chǎng)景
- 不適合大型繼承結(jié)構(gòu)(復(fù)用性差)
六、寄生組合式繼承(最優(yōu)解)
實(shí)現(xiàn)方式:
function inheritPrototype(Child, Parent) { const prototype = Object.create(Parent.prototype); // 創(chuàng)建父類原型的副本 prototype.constructor = Child; // 修復(fù)構(gòu)造函數(shù)指向 Child.prototype = prototype; // 賦值給子類原型 } function Parent(name) { this.name = name; } Parent.prototype.say = function() { return this.name; }; function Child(name) { Parent.call(this, name); // 屬性繼承 } inheritPrototype(Child, Parent); // 方法繼承
特點(diǎn):
- 只調(diào)用一次父類構(gòu)造函數(shù),避免組合繼承的冗余問題
- 保留完整的原型鏈結(jié)構(gòu)
場(chǎng)景:
- 現(xiàn)代項(xiàng)目推薦的標(biāo)準(zhǔn)繼承方式
- 適用于所有復(fù)雜繼承需求(效率最高)
七、ES6 class 繼承
實(shí)現(xiàn)方式:
class Parent { constructor(name) { this.name = name } say() { return this.name } } class Child extends Parent { // extends 關(guān)鍵字 constructor(name) { super(name); // super調(diào)用父類構(gòu)造函數(shù) } } const child = new Child('Child'); child.say(); // 輸出 "Child"
特點(diǎn):
- 語(yǔ)法糖,本質(zhì)基于原型和寄生組合式繼承
- 支持
static
、super
等特性
場(chǎng)景:
- 現(xiàn)代項(xiàng)目首選方式
- 需要清晰類結(jié)構(gòu)、繼承關(guān)系明確的場(chǎng)景
總結(jié)與場(chǎng)景對(duì)比
繼承方式 | 適用場(chǎng)景 | 現(xiàn)代選擇優(yōu)先級(jí) |
---|---|---|
原型鏈繼承 | 快速實(shí)現(xiàn)簡(jiǎn)單原型鏈(已過時(shí)) | ?? |
構(gòu)造函數(shù)繼承 | 需要獨(dú)立實(shí)例屬性的場(chǎng)景 | ???? |
組合繼承 | 傳統(tǒng)項(xiàng)目兼容性解決方案 | ???? |
寄生組合式繼承 | 需要高效且標(biāo)準(zhǔn)的繼承方案 | ???????? |
ES6 class 繼承 | 現(xiàn)代項(xiàng)目開發(fā)(Babel轉(zhuǎn)譯后兼容性好) | ?????????? |
實(shí)際開發(fā)建議:
- 優(yōu)先使用 ES6
class
繼承(清晰、易維護(hù),Babel 轉(zhuǎn)譯后底層使用寄生組合式繼承) - 舊項(xiàng)目維護(hù)時(shí)根據(jù)現(xiàn)有模式選擇組合或寄生組合繼承
4??原型式/寄生式繼承主要用于對(duì)象克隆而非類繼承場(chǎng)景
到此這篇關(guān)于JS 的繼承方式與使用場(chǎng)景的文章就介紹到這了,更多相關(guān)JS 繼承方式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- javascript 高級(jí)語(yǔ)法之繼承的基本使用方法示例
- JavaScript使用prototype原型實(shí)現(xiàn)的封裝繼承多態(tài)示例
- AngularJS中controller控制器繼承的使用方法
- JavaScript使用原型和原型鏈實(shí)現(xiàn)對(duì)象繼承的方法詳解
- Angularjs使用directive自定義指令實(shí)現(xiàn)attribute繼承的方法詳解
- JS面向?qū)ο螅?)之Object類,靜態(tài)屬性,閉包,私有屬性, call和apply的使用,繼承的三種實(shí)現(xiàn)方法
- ExtJS4中使用mixins實(shí)現(xiàn)多繼承示例
相關(guān)文章
javascript禁制后退鍵(Backspace)實(shí)例代碼
這篇文章介紹了javascript禁制后退鍵(Backspace)實(shí)例代碼,有需要的朋友可以參考一下2013-11-11js鼠標(biāo)點(diǎn)擊圖片切換效果實(shí)現(xiàn)代碼
這篇文章為大家分享了js鼠標(biāo)點(diǎn)擊圖片切換效果實(shí)現(xiàn)代碼,特別炫酷的效果,具有一定的參考價(jià)值,推薦給大家,感興趣的小伙伴們可以參考一下2015-11-11layui lay-verify form表單自定義驗(yàn)證規(guī)則詳解
今天小編就為大家分享一篇layui lay-verify form表單自定義驗(yàn)證規(guī)則詳解,具有很好的參考價(jià)值,相信我對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-09-09Three.js利用dat.GUI如何簡(jiǎn)化試驗(yàn)流程詳解
dat.gui可以方便地向場(chǎng)景中添加控制條,隨時(shí)調(diào)整參數(shù)。下面這篇文章主要給大家介紹了關(guān)于Three.js利用dat.GUI如何簡(jiǎn)化試驗(yàn)流程的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧。2017-09-09基于Bootstrap的Metronic框架實(shí)現(xiàn)頁(yè)面鏈接收藏夾功能
本文給大家介紹基于Metronic的Bootstrap開發(fā)框架實(shí)現(xiàn)頁(yè)面鏈接收藏夾功能,非常不錯(cuò),具有參考借鑒價(jià)值,感興趣的朋友一起學(xué)習(xí)吧2016-08-08