2017-01-25 67 views
2

我回答了這個問題:How do objects created? 但我回答後也有問題。如何在構造函數的原型不是對象時創建對象?

function Bar() { 
 
    this.foo = true; 
 
} 
 
console.log('obj3'); 
 
Bar.prototype = 3; 
 
var obj3 = new Bar(); 
 
console.log(obj3); 
 
console.log(obj3.constructor === Bar); 
 
console.log(obj3.constructor === Object); 
 
    
 
console.log(Object.prototype === Object.getPrototypeOf(obj3)); 
 
console.log(obj3.foo);

Bar.prototype = 3,我的理論是,當new Bar()執行,如步驟2,創建的對象應該鏈接到Bar.prototype,但由於Bar.prototype值不指的是一個對象,隱含地指定了一個默認值,即Object.prototype

由於object.prototype.constructor的參考Objectobj3.constructor同時參閱Object,但obj3事實上構造仍然Bar,由於步驟1,其也可以通過console.log(obj3.foo); // true加以證明。

我對不對?

@Leo問我是否可以提供有關內部機制的更多信息。他曾在Firefox Chrome Safari中測試過,他們都表現得一樣,他認爲這應該是ECMA-262中明確規定的。但是,他還沒有到對的地方。但我沒有找到任何支持我的論點的東西,因此我正在尋求你的幫助。你能否提供更多關於內部機制的信息?

回答

6

是的,這是在GetPrototypeFromConstructor指定:

  • 是? Get構造函數"prototype")。
  • 如果Type)沒有對象,然後

    1. 境界是什麼? GetFunctionRealm構造函數)。
    2. 原始是領域的內在對象名爲intrinsicDefaultProto
  • 具體來說,它的工作原理是這樣的:

    1. new Bar()電話Bar. [[Construct]]
    2. 初始化使用
      OrdinaryCreateFromConstructorNEWTARGET"%ObjectPrototype%")的thisArgument
    3. 返回一個對象,它繼承了
      GetPrototypeFromConstructor構造intrinsicDefaultProto

    所以如果prototype不是對象,則默認使用該領域的%ObjectPrototype%。

    注意,它並不總是Object.prototype

    var iframe = document.createElement('iframe'); 
    document.body.appendChild(iframe); 
    var win = iframe.contentWindow; 
    document.body.removeChild(iframe); 
    var F = win.Function("") 
    F.prototype = 5; 
    var proto = Object.getPrototypeOf(new F()); 
    proto === Object.prototype; // false 
    proto === win.Object.prototype; // true 
    
    +0

    非常感謝您的鏈接。在開始的時候,我認爲'obj3.constructor'是'Number',好像'3'被裝箱到它的對象形式,但事實並非如此。然後我開始在規範中搜索。老實說,這個規範很難閱讀。再次感謝。 – Leo

    +0

    @Leo我猜拳擊的數量可能是有意義的,但是當要發生的呢?如果每個實例都生成一個不同的對象,那麼所有的實例都將從不同的對象繼承下來!它可能發生在你設置'prototype'時,但這需要某種setter,這在ES1中不存在。 – Oriol

    +0

    我從你的回答中學到了很多,非常可觀,謝謝! –

    相關問題