總結JS的幾種繼承

2022-08-02 08:54:13 字數 4140 閱讀 4884

最近在學ts的過程中又複習了一遍es5裡面的繼承方式,相信繼承也是很多面試官喜歡問的知識點,特別有筆試題的總是要我們寫一些繼承方法哈哈哈,這裡就跟大家一起來複習和鞏固一下叭叭叭

既然是要實現繼承,當然需要乙個父親了,不然繼承啥是不哈哈哈

父類如下:

// 定義乙個動物類

function animal (name)

//例項引用屬性

this.features = ;

}// 原型方法

animal.prototype.eat = function() ;

複製**

function cat(name)

// test code

var cat = new cat();

console.log(cat.name); //tom

//instanceof 判斷元素是否在另乙個元素的原型鏈上

console.log(cat instanceof animal); // false

console.log(cat instanceof cat); // true

cat.sleep() //tom正在睡覺!

cat.eat() //會報錯cat.eat is not a function

物件冒充可以繼承建構函式裡面的屬性和方法,沒法繼承原型鏈上的屬性和方法

複製**

缺點:

1.例項並不是父類的例項,只是子類的例項

2.只能繼承父類的例項屬性和方法,不能繼承父類原型上的屬性/方法

3.無法實現函式復用,每個子類都有父類例項函式的副本,影響效能

(每個子類都有父類函式的屬性和方法的副本,當cat呼叫animal上的方法時,animal內部的this指向的是catanimal內部的this上的屬性和方法都被複製到了cat上面,如果每個子類的例項都複製一遍父類的屬性和方法,就會占用很大的記憶體,而且當父類的方法發生改變了時,已經建立好的子類例項並不能更新方法,因為已經複製了原來的父類方法當成自己的方法了)

核心: 將父類的例項作為子類的原型 這裡把cat的原型改為是animal的例項,從而實現繼承

重點:讓新例項的原型等於父類的例項。

function cat()

cat.prototype.play = function() ;

cat.prototype = new animal();

cat.prototype.name = 'cat';

// test code

var cat = new cat('zhangsan'); //缺點4傳參也沒效果

var cat1 = new cat('lisi');

cat.name = 'tom';

cat.features.push('red');

console.log(cat instanceof animal); //true

console.log(cat instanceof cat); //true

cat.play() //會報錯cat.play is not a function 缺點1 所以把play方法移動到cat.prototype = new animal()的後面

cat.eat() //cat正在吃! 解決了建構函式實現繼承的缺點2 <(* ̄▽ ̄*)/

cat.sleep() //cat正在睡覺!

//針對父類例項值型別成員的更改,不影響

console.log(cat.name); // "tom"

console.log(cat1.name); // "cat"

//針對父類例項引用型別成員的更改,會通過影響其他子類例項 缺點2

console.log(cat.features); // ['red']

console.log(cat1.features); // ['red']

複製**

缺點:

1.如果要為子類新增屬性或者方法,只能在new animal()之後,並不能放在建構函式中,如上的**示例,如果新增的方法放在改變子類原型的指向之前,改變指向之後新增的方法自然就沒用了,子類的prototype已經指向了父類了

2.子類的所有例項,共用所有的父類屬性,子類不能擁有自己的屬性,如果有多個例項時,其中乙個例項修改了父類引用型別的值,那麼所有的例項都會發生改變,例如我只想其中的乙個例項的features陣列改為['red'],那麼所有的例項該方法都會發生改變

3.不能多繼承,因為是改變了原型鏈的指向,不能指向多個父類,因此只能單繼承

4.建立子類時,無法向父類建構函式傳參,因為在改變子類的原型鏈指向之後,子類的屬性和方法是無效的

核心:通過呼叫父類構造,繼承父類的屬性並保留傳參的優點,然後通過將父類例項作為子類原型,實現函式復用

重點:結合了以上兩種模式的優點,傳參和復用

function cat(name)

cat.prototype = new animal(); //還有另一種寫法 cat.prototype = animal.prototype;

// 組合繼承也是需要修復建構函式指向的。

cat.prototype.constructor = cat;

// test code

var cat = new cat();

console.log(cat.name);

console.log(cat.sleep());

console.log(cat instanceof animal); // true

console.log(cat instanceof cat); // true

複製**

缺點:

這種方式呼叫了兩次父類的建構函式,生成了兩份例項,相同的屬性既存在於例項中也存在於原型中

function cat(name)

this.name = name || 'tom';

}// test code

var cat = new cat();

console.log(cat.name);

console.log(cat.sleep());

console.log(cat instanceof animal); // false

console.log(cat instanceof cat); // true

複製**

缺點:

1.無法獲取父類不可列舉的方法,這種方法是用for in來遍歷animal中的屬性,例如多選框的checked屬性,這種就是不可列舉的屬性

2.效率很低,記憶體占用高

核心:通過寄生方式,砍掉父類的例項屬性,這樣,在呼叫兩次父類的構造的時候,就不會初始化兩次例項方法/屬性,避免的組合繼承的缺點

重點:修復了組合繼承的問題

function cat(name)

(function();

super.prototype = animal.prototype;

//將例項作為子類的原型

cat.prototype = new super();

})();

// test code

var cat = new cat();

console.log(cat.name);

console.log(cat.sleep());

console.log(cat instanceof animal); // true

console.log(cat instanceof cat); //true

幾種js的繼承方式

1 繼承第一種方式 物件冒充 function super username function sub username var supernew new super super var subnew new sub sub supernew.hello subnew.hello subnew.wo...

js的幾種繼承方式

方式一 原型鏈繼承 function parent parent.prototype.getparentname function 子類 function child 下面這步實現繼承,這步需要放在getchildname 之前,不然獲得子類方法無法使用 child.prototype new pa...

JS繼承的幾種方式

1.借助建構函式實現繼承 function parent function child 缺點 只能實現部分繼承。child只能繼承parent建構函式裡面的屬性。不能繼承parent原型鏈上的。2.借助原型鏈實現繼承 function parent function child child.prot...