2010-02-11 18 views
17

考慮下面的代碼:如何查看Javascript對象的原型鏈?

function a() {} 
function b() {} 
b.prototype = new a(); 
var b1 = new b(); 

我們能保持這種a已添加到b的原型鏈。大。而且,所有的下列條件:

b1 instanceof b 
b1 instanceof a 
b1 instanceof Object 

我的問題是,如果我們不知道提前b1起源?我們如何發現其原型鏈的成員?理想情況下,我想要一個像[b, a, Object]["b", "a", "Object"]這樣的數組。

這可能嗎?我相信我在SO的某個地方看到了一個答案,它描述瞭如何發現這一點,但我不能爲了我的生活再次找到答案。

回答

2

您可以使用對象的「構造函數」屬性在那裏找到原型,然後沿着它鏈接,直到到達彩虹的盡頭。

function getPrototypes(o) { 
    return (function gp(o, protos) { 
    var c = o.constructor; 
    if (c.prototype) { 
     protos.push(c.prototype); 
     return gp(c.prototype, protos); 
    } 
    return protos; 
    })(o, []); 
} 

(也許)(或許不是:-)給我一個秒)(以及廢話,我認爲這是可能的,但忽略了代碼)

[編輯]哇,這是完全吹我的腦海 - 該函數接近但不完全正確;建立一連串的原型是奇怪的,我感到害怕和孤獨。我建議只關注上面的真棒@CMS。

+0

'constructor'爲您提供了最近的原型祖先的構造函數,它沒有從另一個構造函數原型繼承。這幾乎從來都不是你想要的。例如在問題的代碼中,'b1.constructor'是'a',而不是'b',如果你從'b'派生出一個對象'c','c1.constructor'仍然是'a'。正常的經驗法則:不要對任何事情使用'constructor'。 [eta:lol @'害怕和孤獨'...是的,這是JavaScript中的一個部分,它旨在通過做一些看起來有用但實際上是陷阱的東西來混淆你的地獄。] – bobince 2010-02-11 16:08:34

+0

是的,我考慮原始問題是一個有趣的練習,但這絕不是我想要實際工作的代碼。這裏有一個非常好的解釋:http://mckoss.com/jscript/object。htm – Pointy 2010-02-11 16:17:37

7

那麼,對象之間的原型鏈接([[Prototype]])是內部的,一些實現,如Mozilla,將其公開爲obj.__proto__

ECMAScript第5版的Object.getPrototypeOf方法是您所需要的,但它現在在大多數JavaScript引擎中都沒有實現。

給由John Resig的一看這implementation,它有一個缺陷,它依賴於發動機的constructor財產不支持__proto__

if (typeof Object.getPrototypeOf !== "function") { 
    if (typeof "test".__proto__ === "object") { 
    Object.getPrototypeOf = function(object){ 
     return object.__proto__; 
    }; 
    } else { 
    Object.getPrototypeOf = function(object){ 
     // May break if the constructor has been tampered with 
     return object.constructor.prototype; 
    }; 
    } 
} 

請記住,這是不是100%可靠,因爲constructor屬性在任何對象上都是可變的。

+2

就像在Javascript中看着對象屬性的任何東西一樣,並且相信你得到的東西是有風險的:-) – Pointy 2010-02-11 05:54:38

+0

謝謝,但是這告訴我'a'是'b1'的原型,但沒有任何關於'b'的內容。我怎麼能發現'b1'是'b'的一個實例? – pr1001 2010-02-11 06:29:36

+0

由於潛在的原型篡改,迴歸到'構造函數'不僅是錯誤的,它開始時完全是錯誤的,因爲'構造函數'不會做你認爲它會做的事情(見下面的註釋)。這顯示了來自Resig的基本JavaScript功能令人驚訝的無知; **不要**使用此腳本。不過,關於'__proto__'和'getPrototypeOf'的信息很好。 – bobince 2010-02-11 16:10:22

0

這裏是一個起點:

Object.prototype.getConstructorNames=function(){ 
     return Object.keys(window).filter(function(e){ 
      return typeof window[e]==="function" && this instanceof window[e]},this) 
    } 

當然,這實在是不完整的,但我認爲它會在大多數情況下,如果有人想給它添加他們可以。