[英]How can I set a default property for an object that's passed into a constructor?
[英]Is this default behaviour for instances whose constructor's prototype property is not set to an object?
function F() {};
F.prototype = "red";
o = new F();
我发现有趣的是,上面的代码片段在控制台中复制时显示,因为对象的[[prototype]]
插槽不能是 object 或null
以外的任何东西, "red"
是不可接受的 & o
的[[prototype]]
插槽似乎只是默认为Object.prototype
。 我可以确认这是实例在构造函数的.prototype
不是 object 时所做的吗?
(有意见认为这是一个不切实际的问题,因为我们为什么要将构造函数的.prototype
重新初始化为 object 以外的其他东西……但我想我还是会问只是检查一下)。
以下是基于 ECMAScript 2020 规范的分析。
首先,很明显prototype
属性可以获取分配给它的任何值。 第19.2.4.3 节原型没有提到具体限制:
除非另有说明,否则“prototype”属性的值用于初始化 object 的 [[Prototype]] 内部插槽,该插槽是在将 function 作为构造函数调用时创建的。
此属性具有属性 { [[Writable]]: true , [[Enumerable]]: false , [[Configurable]]: false }。
通过构造函数创建 object 的过程在第9.2.2 [[Construct]]节中指定。 步骤 5 中描述了关键操作:
OrdinaryCreateFromConstructor( newTarget , "%Object.prototype%" )。
指定为第二个参数的名称很有趣。 从第19.1.2.19 节 Object.prototype我们得知这实际上是Object.prototype
的名称(不足为奇)。
在9.1.13 OrdinaryCreateFromConstructor部分中,我们看到这个参数称为IntrinsicDefaultProto ,其过程的第 2 步依赖于9.1.14 GetPrototypeFromConstructor ,我们最终在第 3 步和第 4 步中进入核心:
- 让原型成为? 获取(构造函数, “原型” )。
- 如果 Type( proto ) 不是 Object,则
- 让realm成为? GetFunctionRealm(构造函数)。
- 将proto设置为realm的内在 object 名为intrinsicDefaultProto 。
So in plain English, this means that if the prototype
property of the constructor is not an object, then Object.prototype
will be used instead for defining the prototype object of the newly constructed object.
这也意味着如果prototype
属性的值为null
,那么仍然构造的 object 将得到Object.prototype
而不是null
作为原型 Z307BA62589CCZ8C1。
要制作对象的原型null
,您需要使用Object.create
。
上面可以用一个小片段来演示。
function F() {}; // Test 1 F.prototype = "red"; console.log("F.prototype: " + F.prototype); // "red" indeed. let o = new F; console.log("Is proto Object.prototype?", Object.getPrototypeOf(o) === Object.prototype); // true // Test 2 F.prototype = null; console.log("F.prototype: " + F.prototype); // null indeed. o = new F; console.log("Is proto Object.prototype?", Object.getPrototypeOf(o) === Object.prototype); // true // Test 3 o = Object.create(null); console.log("Is proto of Object.create(null) null?", Object.getPrototypeOf(o) === null); // true
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.