js繼承的13種方式
也可以說只有12種,ES6的extend 也是12種方法之一-寄生繼承的語法糖
1、原型鏈法
程式碼示例
Child.prototype = new Parent();
所屬模式:
1、基於構造器工作方式
2、使用原型鏈模式
技術註解
1、預設繼承機制
2、提示:我們可以將方法與屬性集中可重用的部分遷移到原型鏈中,而將不可重用的那部分設定為物件的自身屬性
詳細程式碼解釋
2、僅從原型鏈繼承法
程式碼示例
Child.prototypo = Parent.prototype
所屬模式
1、基於構造器工作模式
2、原型拷貝模式(不存在原型鏈,所有物件共享一個原型)
技術註解
1、由於該模式在構建繼承關係時不需要新建例項,效率上有較好的表現
2、原型鏈上的查詢也會比較快,因為這裡根本不存在鏈
3、缺點在於,對子物件的修改會直接影響其父物件
詳細程式碼註解
3、臨時構造器法
程式碼示例
function extend(Child, Parent){
var F = function(){};
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;
Child.uber = Parent.prototype
}
所屬模式
1、基於構造器工作的模式
2、使用原型鏈模式
技術註解
1、此模式不同於1號方法,它只繼承父物件的原型屬性,而對其自身屬性(也就是被構造器新增到this值中的屬性)則不予繼承;
2、另外,該模式還為我們訪問父物件提供了便利的方法(通過uber 屬性)
詳細程式碼註解
4、原型屬性拷貝法
程式碼示例
function extend2(Child, Parent){
var p = Parent.prototype;
var c = Child.prototype;
for(var i in p) {
c[i] = p[i]
}
c.uber = p
}
所屬模式
1、基於構造器工作的模式
2、使用原型鏈模式
3、拷貝屬性模式
技術註解
1、將父物件原型中的內容全部轉換成子物件原型屬性
2、無須為繼承單獨建立物件例項
3、原型鏈本身也更短
詳細程式碼註解
5、全屬性拷貝法(淺拷貝法)
程式碼示例
function extend2(p){
var c = {};
for(var i in p) {
c[i] = p[i]
}
c.uber = p
return c
}
所屬模式
1、基於物件工作模式
3、拷貝屬性模式
技術註解
1、非常簡單
2、沒有使用原型屬性
詳細程式碼註解
6、深拷貝法
程式碼示例
let deepCopy = function (child, parent){
var child = child || {};
for(var i in parent) {
if(typeof parent[i] === "object") { // 引用型別的判斷
child[i] = Array.isArray(parent[i]) ? [] : {}; // child[i] 跟這個parent[i] 走
deepCopy(child[i], parent[i]);
} else {
child[i] = parent[i]
}
}
return child;
}
所屬模式
1、基於物件工作模式
3、拷貝屬性模式
技術註解
1、非常簡單
2、沒有使用原型屬性
3、所有物件執行的都是值傳遞
詳細程式碼註解
7、原型繼承法
程式碼示例
function object(o){
function F() {}
F.prototype = o;
return new F();
}
所屬模式
1、基於物件工作模式
2、使用原型鏈模式
技術註解
1、丟開仿類機制,直接在物件之間構造繼承關係
2、發揮原型固有優勢
詳細程式碼註解
8、擴充套件與增強模式
程式碼示例
function objectPlus(o, stuff){
var n ;
function F(){};
F.prototype = o;
n = new F();
n.uber = o;
for(var i in stuff) {
n[i] = stuff[i];
}
return n;
}
所屬模式
1、基於物件工作模式
2、使用原型鏈模式
3、屬性拷貝模式
技術註解
1、原型繼承法和屬性拷貝法的混合應用
2、它通過一個函式一次性完成物件的繼承和擴充套件
詳細程式碼註解
9、多重繼承法
程式碼示例
function multi(){
var n = {}, stuff, j, len = arguements.length;
for(j = 0; j < len; j++) {
stuff = arguments[j];
for(var i in stuff) {
n[i] = stuff[i]
}
}
return n
}
所屬模式
1、基於物件工作模式
2、屬性拷貝模式
技術註解
1、混合插入式繼承實現
2、它會按照父物件的出現順序一次對它們執行屬性全拷貝
詳細程式碼註解
10、寄生繼承法
程式碼示例
function parasite(){
var that = Object.create(victim);
that.more = 1;
return that;
}
所屬模式
1、基於物件工作模式
2、使用原型鏈模式
技術註解
1、該方法通過一個類似構造器的函式來建立物件
2、該函式會執行相應的物件拷貝,並對其進行擴充套件,然後返回該拷貝
詳細程式碼註解
11、構造器借用法
程式碼示例
function Child(){
Parent.apply(this, arguements)
}
所屬模式
1、基於構造器工作模式
技術註解
1、該方法可以只繼承父物件的自身屬性
2、可以與方法1結合使用,以便從原型中繼承相關內容
3、它便於我們的子物件繼承某個物件具體屬性(並且還有可能是引用型別屬性)時,選擇最簡單的處理方式
詳細程式碼註解
12、構造器借用與屬性拷貝
程式碼示例
function Child(){
Parent.apply(this, arguements)
}
extend2(Child, Parent)
所屬模式
1、使用構造器工作模式
2、使用原型鏈模式
3、屬性拷貝模式
技術註解
1、該方法是構造器借用與屬性拷貝法結合體
2、允許我們在不重複呼叫父物件建構函式的情況下同時繼承其自身屬性和原型屬性
詳細程式碼註解
13、ES6 extend
程式碼示例
let Parent = function () {};
class Child extend Parent {
constructor(){
super(this)
}
}
所屬模式
1、基於物件工作模式
2、使用原型鏈模式
技術註解
1、該方法是寄生繼承法的語法糖
2、可以用babel 將其轉化一下,就能看到它實際的工作模式(寄生繼承, Object.create(obj))
詳細程式碼註解
參考
《javascript物件導向程式設計指南》