JavaScript中internal [[prototype]]属性的默认值是什么?

时间:2015-06-12 14:49:36

标签: javascript oop

每个对象都有[[prototype]]属性。默认情况下,它是全局Object构造函数的实例。

令我困惑的是这段代码:

var obj1 = {};
var obj2 = {};

console.log(obj1.__proto__ == obj2.__proto__); //true

这两个对象的[[prototype]]引用Object的相同实例。

我的问题是:JavaScript是否有Object的保留实例,在我们未指定[[prototype]]值的任何地方使用?

3 个答案:

答案 0 :(得分:2)

  

默认情况下,它是一个全局Object构造函数的实例。

默认情况下,每个原型链中的最后一个对象是Object.prototype。它实际上不是Object的实例:

> Object.prototype instanceof Object
false

只是因为Object.prototype本身没有原型。

  

JavaScript是否有一个Object的保留实例,在我们没有指定[[prototype]]值的地方使用它?

见上文。

答案 1 :(得分:0)

javascript中对象的原型是其构造函数的原型属性。

如果您定义了一个新的构造函数:

function MyConstructor() {}

从中实例化的所有对象都具有相同的原型,即MyConstructor.prototype。

var a = new MyConstructor();
var b = new MyConstructor();
console.log(a.__proto__ == b.__proto__); //true

在您的特定情况下,您使用内联对象{}此对象是使用默认的Object()构造函数创建的,因此它们共享相同规则的原型。

答案 2 :(得分:0)

我认为answer by Felix Kling部分正确。 根据{{​​3}},JS定义了多种对象,例如-

  1. ECMA 2019
  2. Ordinary Objects
  3. Function Objects
  4. Built-in Function objects
  5. Built-in Exotic Object

基于这些对象类型,定义了[[Prototype]]的默认值。

示例1 :对于像创建let p1 = new Person();这样的普通对象,我们将Person.protoype作为[[Prototype]]的{​​{1}}值。我引用了Proxy Objects

9.1.13 OrdinaryCreateFromConstructor(构造函数,internalDefaultProto [,internalSlotsList])

抽象操作OrdinaryCreateFromConstructor创建一个 普通对象,其 [[Prototype]]值是从 构造函数的原型属性(如果存在)。否则 由[internalDefaultProto]命名的内在函数用于[[Prototype]]。 可选的internalSlotsList是其他名称的列表 内部插槽,必须将其定义为对象的一部分。如果清单 未提供,则使用新的空列表。这个抽象操作 执行以下步骤:

  1. 声明:nativeDefaultProto是一个String值,它是此规范的内部对象名称。对应对象 必须是打算用作[[Prototype]]的内在函数 对象的值。
  2. 让我们成为? GetPrototypeFromConstructor(constructor,nativeDefaultProto)。
  3. 返回ObjectCreate(proto,internalSlotsList)。

示例2 :让我们再举一个功能对象的示例。我们有以下代码:

p1

我再次引用ECMA 2019

9.2.3 FunctionAllocate(functionPrototype,strict,functionKind)抽象操作FunctionAllocate需要三个参数 functionPrototype,strict和functionKind。 FunctionAllocate执行 以下步骤:

  1. 声明:Type(functionPrototype)是对象。
  2. 声明:functionKind是“正常”,“非构造函数”,“生成器”,“异步”或“异步生成器”。
  3. 如果functionKind为“ normal”,则将needsConstruct为true。
  4. 否则,让needsConstruct为false。
  5. 如果functionKind是“非构造函数”,请将functionKind设置为“普通”。
  6. 让F为一个新创建的ECMAScript函数对象,其内部插槽在表27中列出。所有这些内部插槽均为 初始化为未定义。
  7. 将F的基本内部方法设置为9.1中指定的默认普通对象定义。
  8. 将F。[[Call]]设置为9.2.1中指定的定义。
  9. 如果needsConstruct为true,则 一种。将F。[[Construct]]设置为9.2.2中指定的定义。 b。将F。[[[ConstructorKind]]设置为“基本”。
  10. 将F。[[Strict]]设置为严格。
  11. 将F。[[[FunctionKind]]]设置为functionKind。
  12. 将F。[[Prototype]]设置为functionPrototype。
  13. 将F。[[Extensible]]设置为true。
  14. 将F。[[[Realm]]]设置为当前的Realm记录。
  15. 返回F。

functionPrototype 仅是var foo = function(){}; function hoo(){}; console.log(foo.__proto__== Function.prototype);//true console.log(hoo.__proto__== Function.prototype);//true