2011-12-09 67 views
23

考慮與原型鏈這樣一個對象:INSTANCEOF等值的Object.create和原型鏈

var A = {}; 
var B = Object.create(A); 
var C = Object.create(B); 

如何檢查在運行時,如果C有一個在它的原型鏈?

instanceof不適合,因爲它設計用於構造函數,我不使用這裏。

回答

21

我的回答將是短...

你可以使用isPrototypeOf方法,它會出現在你的情況下,從目標對象的原型繼承,喜歡你的例子。

例如:

A.isPrototypeOf(C) // true 
B.isPrototypeOf(C) // true 
Array.prototype.isPrototypeOf(C) // false 

更多信息可以在這裏讀到:Mozilla Developer Network: isPrototypeOf

+1

+1簡單的解決方案。雖然你的例子是完全正確的,但它會是'Array.prototype.isPrototypeOf(C)'來檢查'C'是否是一個數組(我發現你的最後一個例子有點模棱兩可 - 在函數上使用'isPrototypeOf'通常不是你想要什麼)。 – pimvdb

+0

你完全正確,我不想因爲當時已經給出答案而失去太多時間,所以我沒有想太多的例子,我的目標只是顯示可用的方法。 。我仍然會糾正給出的例子與你的答案,因爲正如你所說,我同意,我的最後一個例子是模棱兩可的,謝謝你的通知=) – Couto

+0

只是一個簡單的問題:如何可能的對象不可以從Object繼承?任何對象都有一個[[Prototype]]引用,通過原型鏈最終導致Object.prototype。 –

4

您可以通過遞歸調用Object.getPrototypeOf迭代回原型鏈:http://jsfiddle.net/Xdze8/

function isInPrototypeChain(topMost, itemToSearchFor) { 
    var p = topMost; 

    do { 

     if(p === itemToSearchFor) { 
      return true; 
     } 

     p = Object.getPrototypeOf(p); // prototype of current 

    } while(p); // while not null (after last chain) 

    return false; // only get here if the `if` clause was never passed, so not found in chain 
} 
+0

+1正要張貼接近* *相同的答案,甚至用'做-while',這我不不要太頻繁地看。但是你的功能更加優秀。 – RightSaidFred

+0

@RightSaidFred:有趣的是,我還在考慮使用'do'關鍵字這一事實,我幾乎從不這樣做。 – pimvdb

+0

我很驚訝沒有一個針對ES6的Object.hasPrototype提案,它完全符合你的功能。它看起來像'instanceof'的自然補充'Object.create'是'new Constructor'。它甚至可以接受一個函數作爲第二個參數,它將使用函數的'prototype'作爲目標。 – RightSaidFred