How objects are created when the prototype of their constructor isn't an object?

て烟熏妆下的殇ゞ 提交于 2019-12-24 00:29:06

问题


I answered this question: How do objects created? but I also have a question after I answered it.

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, my theory is that, when new Bar() executed, as in Step 2, the created object is supposed to linked to Bar.prototype, but since the value of Bar.prototype doesn't refer to an object, implicitly a default value was assigned, which is the Object.prototype.

Due to object.prototype.constructor's reference to the Object, obj3.constructor also refer to the Object, but obj3's de facto constructor is still Bar, because of Step 1, which also can be proved by console.log(obj3.foo); // true.

Am I right?

@Leo asked me if I could provide more information about the internal mechanism. He had tested it in Firefox Chrome Safari, they all behave the same, he thinks it should be something clearly specified in ECMA-262. However, he hasn't got to the right place. But I didn't find anything to support my argument too, therefore I'm looking for your help. Could you provide more information about the internal mechanism?


回答1:


Yes, this is specified in GetPrototypeFromConstructor:

  1. Let proto be ? Get(constructor, "prototype").
  2. If Type(proto) is not Object, then

    1. Let realm be ? GetFunctionRealm(constructor).
    2. Let proto be realm's intrinsic object named intrinsicDefaultProto.

Specifically, it works like this:

  1. new Bar() calls Bar.[[Construct]]
  2. That initializes the thisArgument using
    OrdinaryCreateFromConstructor(newTarget, "%ObjectPrototype%")
  3. That returns an object which inherits from
    GetPrototypeFromConstructor(constructor, intrinsicDefaultProto)

So if the prototypeis not an object, the default will be the %ObjectPrototype% of that realm.

Note that it's not always 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


来源:https://stackoverflow.com/questions/41846565/how-objects-are-created-when-the-prototype-of-their-constructor-isnt-an-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!