【问题标题】:new keyword, new Object() and Object.create() in JavascriptJavascript 中的 new 关键字、new Object() 和 Object.create()
【发布时间】:2017-09-28 07:48:43
【问题描述】:

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

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,但是它获得了引用TestObjectconstructor 属性。它只能访问TestObject的原型成员。

Object.create()

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

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

问题

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

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

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

【问题讨论】:

    标签: javascript object inheritance prototype prototypal-inheritance


    【解决方案1】:

    下面一行:

    TestObject.prototype.TestProperty2 = "TestProperty2";
    

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

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

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

    因此,不是直接从TestObject 继承,而是从具有指定原型的Object 继承。对其进行的任何更改都不会影响最初的更改。

    EnchancedTestObject.prototype = new TestObject();
    

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

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

    【讨论】:

    • 不是伪经典继承吗?
    • @user8056359 是的,但在 ES2015 中引入 class 关键字之前,这是唯一的选择(这也是语法糖),Javascript 仍然是基于原型的。
    【解决方案2】:

    new TestObject(); 正是我的 OOP 经验所期望的。

    是的。您应该使用它,并且只使用它。

    new Object(TestObject.prototype); 是 Object 类型而不是 TestObject,但是它获得了一个引用 TestObject 的构造函数属性。它只能访问 TestObject 的原型成员。

    不完全是。它TestObject 的原型对象,这就是它具有.constructor 属性和其他成员的原因。当您将new Object 与一个对象作为参数一起使用时,它实际上 创建一个new 对象,它只是返回参数。你的TestInstance2 === TestObject.prototype

    Object.create(TestObject.prototype); 属于 TestObject 类型,但它只能访问其原型成员。

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

    为什么要使用new Object() 方法而不是new 关键字方法?

    没有理由使用new Object。应该始终使用对象字面量来构造空对象,或者直接使用 Object(x)(没有 new)将 x 转换为一个对象(如果它还不是一个对象)。

    在标准的第一版中,new 关键字方法是否与 new Object() 方法一样可用?

    是的,一直都是这样。

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

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

    【讨论】:

    • new 关键字是伪经典继承? new Object() 是原型继承? Object.create() 是原型继承?
    • @user8056359 new 关键字是通过构造函数进行原型继承和初始化。 Object.create 是原型继承。 new Object 什么都不是。
    猜你喜欢
    • 1970-01-01
    • 2012-10-13
    • 2016-12-04
    • 2012-03-10
    • 2012-05-08
    • 2020-12-07
    • 1970-01-01
    • 1970-01-01
    • 2010-12-11
    相关资源
    最近更新 更多