当构造函数的原型不是对象时,如何创建对象?

时间:2022-05-23 19:19:04

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.

酒吧。prototype = 3,我的理论是,当执行new Bar()时,如步骤2中所示,创建的对象应该链接到Bar。样机,但自值杆。prototype不引用一个对象,默认值是被指定的,这是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.

由于object.prototype。构造函数对对象obj3的引用。构造函数也引用对象,但是obj3的实际构造函数仍然是Bar,因为步骤1也可以由console.log(obj3.foo)证明;/ /正确的。

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?

@Leo问我是否可以提供更多关于内部机制的信息。他在Firefox Chrome Safari上测试过,它们的表现都是一样的,他认为应该是ECMA-262中明确规定的。然而,他并没有到达正确的地方。但是我也没有找到任何支持我的论点的东西,所以我在寻求你的帮助。你能提供更多关于内部机制的信息吗?

1 个解决方案

#1


6  

Yes, this is specified in GetPrototypeFromConstructor:

是的,这是在getprototypefrom构造函数中指定的:

  1. Let proto be ? Get(constructor, "prototype").
  2. 让原型是什么?(构造函数,“原型”)。
  3. If Type(proto) is not Object, then

    如果类型(proto)不是对象,则

    1. Let realm be ? GetFunctionRealm(constructor).
    2. 让领域是什么?GetFunctionRealm(构造函数)。
    3. Let proto be realm's intrinsic object named intrinsicDefaultProto.
    4. 让proto成为领域内的内在对象,命名为intrinsic defaultproto。

Specifically, it works like this:

具体来说,它是这样工作的:

  1. new Bar() calls Bar.[[Construct]]
  2. 新栏()调用栏。[[制造]]
  3. That initializes the thisArgument using
    OrdinaryCreateFromConstructor(newTarget, "%ObjectPrototype%")
  4. 使用ordinarycreatefrom构造函数初始化这个参数(newTarget,“%ObjectPrototype%”)
  5. That returns an object which inherits from
    GetPrototypeFromConstructor(constructor, intrinsicDefaultProto)
  6. 它返回一个对象,该对象继承自getprototypefrom构造函数(构造函数,intrinsicDefaultProto)

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

因此,如果prototype不是对象,那么默认值将是该领域的%ObjectPrototype%。

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

#1


6  

Yes, this is specified in GetPrototypeFromConstructor:

是的,这是在getprototypefrom构造函数中指定的:

  1. Let proto be ? Get(constructor, "prototype").
  2. 让原型是什么?(构造函数,“原型”)。
  3. If Type(proto) is not Object, then

    如果类型(proto)不是对象,则

    1. Let realm be ? GetFunctionRealm(constructor).
    2. 让领域是什么?GetFunctionRealm(构造函数)。
    3. Let proto be realm's intrinsic object named intrinsicDefaultProto.
    4. 让proto成为领域内的内在对象,命名为intrinsic defaultproto。

Specifically, it works like this:

具体来说,它是这样工作的:

  1. new Bar() calls Bar.[[Construct]]
  2. 新栏()调用栏。[[制造]]
  3. That initializes the thisArgument using
    OrdinaryCreateFromConstructor(newTarget, "%ObjectPrototype%")
  4. 使用ordinarycreatefrom构造函数初始化这个参数(newTarget,“%ObjectPrototype%”)
  5. That returns an object which inherits from
    GetPrototypeFromConstructor(constructor, intrinsicDefaultProto)
  6. 它返回一个对象,该对象继承自getprototypefrom构造函数(构造函数,intrinsicDefaultProto)

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

因此,如果prototype不是对象,那么默认值将是该领域的%ObjectPrototype%。

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