非ES6代碼實現繼承的主流方式主要可以分為:
構造繼承、原型鏈繼承、構造繼承+原型鏈繼承組合繼承、以及在組合繼承上衍生出的繼承方式。
構造繼承 (借助call實現)
實現
1
2
3
4
5
6
7
8
9
10
11
12
13
|
function Super(age){ this .age = age; this .say = function (){ console.log( this .age) } } function Child(name,age){ Super.call( this ,age) this .name = name; } var child = new Child( "min" ,23) console.log(child instanceof Super); // false console.log(child instanceof Child); // true |
優點
(1) 可以實現多繼承(call多個父類對象)
(2) 構造函數中可向父級傳遞參數
缺點
(1) 只能繼承父類實例的屬性和方法,不能繼承原型上的屬性和方法
(2) 實例并不是父類的實例,只是子類的實例
原型鏈繼承 (借助原型鏈實現)
實現
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
function Super(){ this .getName = function (){ console.log( this .name) } } function Child(name){ this .name = name; } Child.prototype = new Super(); // 這里可以傳構造參數 Child.prototype.constructor = Child; var child = new Child( "min" ); console.log(child instanceof Super); // true console.log(child instanceof Child); // true console.log(child.constructor); // Child |
優點
(1) 父類原型屬性與方法,子類都能訪問到
(2) 實例是子類的實例,也是父類的實例
缺點
(1) 無法實現多繼承 (2) 創建子類實例時,無法向父類構造函數傳參
組合繼承 (構造繼承+原型鏈繼承)
實現
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
function Super(age){ this .age = age; this .getAge = function (){ console.log( this .age); } } function Child(name,age){ Super.call( this ,age) this .name = name; } Child.prototype = new Super(1); Child.prototype.constructor = Child; var child = new Child( "min" ,23); console.log(child instanceof Super); // true console.log(child instanceof Child); // true console.log(child.constructor); // Child |
優點
(1) 結合了構造+原型鏈繼承的優點
缺點
(1) Child.prototype = new Super(); 多調用了一次,使得原型對象中存在一些不必要屬性,如上面例子中age屬性
寄生組合繼承
實現
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
function Super(age){ this .age = age; this .getAge = function (){ console.log( this .age) } } function Child(name,age){ Super.call( this ,age) this .name = name; } ( function (){ function Copy(){} Copy.prototype = Super.prototype; Child.prototype = new Copy(); })() Child.prototype.constructor = Child; var child = new Child( "min" ,23); |
備注
問:為什么沒有直接使用 Child.prototype = Super.prototype;
答:Child.prototype.constructor = Child;關鍵代碼,上面寫Super.prototype 也會變(引用類型,指向同一地址)
優點
(1) 這應該是實現繼承最完美的方案了,es6的extends關鍵字,在babel轉換后代碼也是通過這種方式實現的繼承。
額外:借助(Object.create)
實現
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
function Super(age){ this .age = age; this .getAge = function (){ console.log( this .age) } } function Child(name,age){ Super.call( this ,age) this .name = name; } Child.prototype = Object.create(Super.prototype,{ constructor:{ // 構造函數修復 value: Child } }) var child = new Child( "min" ,23); console.log(child instanceof Super); // true console.log(child instanceof Child); // true console.log(child.constructor); // Child |
以上就是JavaScript 實現繼承的幾種方式的詳細內容,更多關于JavaScript 實現繼承的資料請關注服務器之家其它相關文章!
原文鏈接:https://juejin.cn/post/6928702425016565774