Javascript 中的新关键字、new Object() 和 Object.create()

new keyword, new Object() and Object.create() in Javascript

我需要一些关于对象实例化和继承的说明。考虑以下代码和后续观察:

function TestObject() {
  this.TestProperty1 = "TestProperty1";
  this.TestFunction1 = function() {
    console.log(this.TestProperty1);
  }
}

TestObject.prototype.TestProperty2 = "TestProperty2";
TestObject.prototype.TestFunction2 = function() {
  console.log(this.TestProperty2);
}

new 关键词

let TestInstance1 = new TestObject();
console.log(TestInstance1);

根据我的 OOP 经验,输出正是我所期望的。 TestInstance1 属于 TestObject 类型,它可以访问其成员和原型成员。

new Object()

let TestInstance2 = new Object(TestObject.prototype);
console.log(TestInstance2);

输出表明 TestInstance2 是类型 Object 而不是 TestObject 但是它得到一个 constructor 属性 引用 TestObject.它只能访问 TestObject.

的原型成员

Object.create()

let TestInstance3 = Object.create(TestObject.prototype);
console.log(TestInstance3);

输出表明 TestInstance3 属于 TestObject 类型,但它只能访问其原型成员。

问题

为什么要使用 new Object() 方法而不是 new 关键字方法? return 一个 Object 实例引用传递给它的构造函数的类型而不是简单地 return 一个类型本身的实例似乎很奇怪。

第一版标准中是否提供了 new 关键字方法,就像 new Object() 方法一样?我的印象是它是后来添加的,因为我看不出有任何理由使用 new Object() 方法而不是 new 关键字方法。

由于 Object.create() 是最近才添加到该语言中的,它打算解决什么问题?

下面一行:

TestObject.prototype.TestProperty2 = "TestProperty2";

修改所有 TestObject 个实例,这通常不是您要实现的目标。

Object.create()方法用于实现经典继承。 如:

EnchancedTestObject.prototype = Object.create(TestObject.prototype);

因此,您不是直接从 TestObject 继承,而是从 Object 继承指定的原型。对其所做的任何更改都不会影响初始版本。

EnchancedTestObject.prototype = new TestObject();

您通常也不想在这里创建新的 TestObject 实例。如果 TestObject 期望参数会发生什么?你会通过哪一个?如果调用 TestObject 构造函数有副作用怎么办?

解决方案是将 TestObject.prototype 挂接到原型链中。

new TestObject(); is exactly what I would expect given my OOP experience.

是的。你应该使用它,而且只使用它。

new Object(TestObject.prototype); is of the type Object and not TestObject however it gets a constructor property which references TestObject. It only has access to the prototype members of TestObject.

不完全是。它TestObject的原型对象,这就是为什么它有.constructor属性和其他成员。当你使用 new Object 和一个对象作为参数时,它实际上 而不是 创建一个 new 对象,它只是 returns 的说法。你的TestInstance2 === TestObject.prototype.

Object.create(TestObject.prototype); is of the type TestObject but it only has access to its prototype members.

是的。与 new 不同,它没有 运行 初始化实例的构造函数。

Why would one want to use the new Object() method instead of the new keyword method?

没有理由使用 new Object。人们应该总是使用和对象文字来构造空对象,或者只是简单的 Object(x)(没有 new)将 x 转换为一个对象,如果它还不是一个对象的话。

Was the new keyword method available in the first edition of the standard just like the new Object() method was?

是的,一直都是这样。

Since Object.create() was added rather recently to the language, what issue was it intended to solve?

在没有 运行 函数的情况下获得原型继承。这对很多事情都很有用,比如为 类 创建原型继承链或克隆对象。它还允许我们构造没有原型的对象(不继承任何东西),类似于 Object.prototype,通过调用 Object.create(null).