2015-06-23 48 views
10

我有一種情況,我需要檢查構造函數(X)是否在其原型鏈(或Y本身)中有另一個構造函數(Y)。檢查構造函數是否在ES6中繼承另一個構造函數

最快的方法可能是(new X()) instanceof Y。在這種情況下,這不是一個選項,因爲如果沒有有效的參數,實例化的構造函數可能會拋出異常。

下一個方法我已經考慮是這樣的:

const doesInherit = (A, B) => { 
    while (A) { 
    if (A === B) return true; 
    A = Object.getPrototypeOf(A); 
    } 

    return false; 
} 

這一工程,但我不能動搖我錯過了一些更簡單的方法來檢查這個意識。有一個嗎?

+0

'Object.getPrototypeOf(A)instanceof B'應該可以工作,我想。 –

+0

這就是我上面使用的(但是==),它確實有效(儘管它需要循環,因爲繼承並不總是直接的)。或者我誤解了? – Semicolon

+0

不,我的觀點是使用Object.getPrototypeOf(A)instanceof B'而不是循環。你正在做一些完全不同的事情:P –

回答

19

因爲這樣instanceof作品,你應該能夠做到

A.prototype instanceof B 

但這隻會測試繼承,你應該有比較A === B測試請自行參考:

A === B || A.prototype instanceof B 

Babel example

class A {} 
class B extends A {} 
class C extends B {} 

console.log(C === C) // true 
console.log(C.prototype instanceof B) // true 
console.log(C.prototype instanceof A) // true 

instanceof基本上實現如下:

function instanceof(obj, Constr) { 
    var proto; 
    while ((proto = Object.getProtoypeOf(obj)) { 
    if (proto === Constr.prototype) { 
     return true; 
    } 
    } 
    return false; 
} 

它遍歷所述對象和檢查的原型鏈任何原型是否等於構造prototype屬性。

所以幾乎就像你在做什麼,但內部。

+1

謝謝。 'instanceof'邏輯也很好理解。我忘了一個構造函數的prototype屬性本身就是超級構造函數的一個實例 - 就像人們擔心的一樣,它必須是所有'class糖'給我的東西:> – Semicolon

+0

你不小心把兩個左括號'((原型)。 ..' – Fahmi

+0

@Fahmi:這是故意的,表明我真的想要在這裏發生一個任務而不是比較(即它表示'='不是一個錯字)。 –

13

還有Object.prototype.isPrototypeOf()。似乎是一個完美的用例,不是嗎?

Babel

class A {} 
class B extends A {} 
class C extends B {} 
console.log(C === C) 
console.log(B.isPrototypeOf(C)) 
console.log(A.isPrototypeOf(C)) 
+1

哇,是的,那太好了,這正是我所想象的,但在拖網MDN的時候我一定錯過了它,我希望我可以接受這兩個答案,但是我會和費利克斯一起離開綠色支票,因爲它也是正確和徹底的 – Semicolon

+1

爲什麼我從來沒有使用該功能,即使它自ES3以來就存在? –

+0

不知道,但它絕對是在雷達下飛行。當我第一次讀到它時,我認爲它是未來規範 - 這些ES6之一*'看看我們迄今爲止忘記放入語言中'的方法*類型。 – Oka

1

當心:檢查ES6類A的以上回答,B,C的繼承鏈與isPrototypeOf()巨大的。但它不喜歡你的工作可能期望預ES6類對象,數組等功能

Object.prototype.isPrototypeOf (Array.prototype); // => true 

但是:

Object.isPrototypeOf (Array); // => false 

這就好比是應該的。 Array的INSTANCES繼承Object.prototype的方法。但是「類」數組不會繼承「類」對象。如果您向Object添加方法,則無法通過Array調用它。數組不會繼承Object的方法(如果有的話)。只是用戶創建的類的工作方式不同!

也許我們不應該將Object和Array和Function視爲「類」 - 即使您可以創建它們的實例。他們只是「建設者」。或者我們可以說它們是類,但JavaScript中的內置類與用戶創建的類不同。

+0

非常好的一點,我沒有考慮到這一點。 – Semicolon