JS組合繼承相比原型鏈繼承的優勢

2021-08-22 11:31:39 字數 2381 閱讀 5911

原型繼承:

// '父'建構函式

function father() {

this.name = 'foo';

this.family = ['jack','tom','james'];

father.prototype.sayname = function () {

console.log(this.name);

father.prototype.sayfamily = function () {

// '子'建構函式

function child() {

// 實現繼承

child.prototype = new father();

// 看看繼承之後的效果

let childinstance1 = new child();

childinstance1.sayname(); // 'foo'

childinstance1.sayfamily(); // ['jack','tom','james']

通過將子建構函式的原型設定為父建構函式例項的方法實現了繼承,這就是原型鏈繼承。在這個例子中,子建構函式的例項本身是沒有 name 和 family 屬性的,這兩個屬性都是通過原型鏈在子建構函式的原型上找到的,而子建構函式的原型來自于父建構函式的乙個例項。 子建構函式的例項本身也是沒有 sayname 和 sayfamily 方法的,沿著原型鏈查詢,子建構函式的原型中也沒有這兩個方法,再向上查詢,這兩個方法來自與父建構函式的原型上。

原型鏈繼承的問題:

通過這種繼承方法,有乙個比較明顯的問題,我們知道,引用型別的原型屬性會被所有的例項共享,那麼在上面的例子中,由於子建構函式的原型是父建構函式的例項,所以 family 屬性(陣列是引用型別)會被子建構函式的所有例項共享。也就是說,當我們修改了子建構函式乙個例項上的 family 屬性時,會對子建構函式原型上的該屬性直接產生影響,從而影響到子建構函式的全部例項。

// 修改childinstance2的屬性值,看看會有什麼影響

let childinstance2 = new child();

childinstance2.name = 'bar';

childinstance2.family.push('curry');

childinstance1.sayname(); // 'foo'

childinstance1.sayfamily(); // ['jack','tom','james','curry']

childinstance2.sayname(); // 'bar'

childinstance2.sayfamily(); // ['jack','tom','james','curry']

我們看到,修改了 childinstance2 的 name 屬性(字串是基礎型別),不會對其他例項產生影響,但是當我們修改了 family 屬性時,就會造成 childinstance1 的 family 屬性也被修改了。這顯然會帶來很多的麻煩。

組合繼承:思路是通過原型鏈實現對原型屬性和方法的繼承,但是利用建構函式實現對例項屬性的繼承,避免屬性被共享。

// '父'建構函式

function father() {

this.family = ['jack','tom','james'];

father.prototype.sayfamily = function () {

console.log(this.family);

// '子'建構函式

// 這裡利用建構函式把父建構函式的屬性直接放到子建構函式屬性中

function child() {

father.call(this);

// 實現繼承

child.prototype = new father();

// 看看繼承之後的效果

let childinstance1 = new child();

childinstance1.sayfamily(); // ['jack','tom','james']

// 修改subinstance2的屬性值,看看會有什麼影響

let childinstance2 = new child();

childinstance2.family.push('curry');

childinstance1.sayfamily(); // ['jack','tom','james']

childinstance2.sayfamily(); // ['jack','tom','james','curry']

採用組合繼承,子建構函式創造出來的例項本身就有 family 屬性(建構函式具有的屬性和方法都在例項本身),不必再通過原型鏈向原型查詢,也就避免了屬性被共享的問題。

js繼承,原型鏈繼承

1 乙個型別的物件能夠訪問另外乙個型別的屬性和方法 2 類與類之間的關係 類就是眾多例項共有的屬性和方法的乙個抽象 function animal name animal.prototype.say function function dog 把子類的原型指向父類的例項 dog.prototype ...

11 03 繼承,原型鏈 組合繼承

1.介面繼承在ecmascript中是不可能的,因此實現繼承是ecmascript唯一支援的繼承方式,因此顯示中主要是通過原型鏈繼承。subtype的原型指向supertype的原型,因此繼承它的所有原型上的屬性和方法,若例項把所繼承來的方法遮避了,相當於建構函式下的方法被重寫了。2.原型和繼承的關...

js 原型鏈繼承

建構函式的prototype的 proto 預設指向object.prototype,是繼承object。function animal age animal.prototype.getage function animal.prototype.eat function function dog n...