【问题标题】:What is the real difference between new vs Object.create() [duplicate]new 与 Object.create() 之间的真正区别是什么 [重复]
【发布时间】:2017-12-15 11:08:06
【问题描述】:

我试图了解关键字newObject.create() 之间的真正区别

说明:

  • a1functiona2object
  • a1a2key1 作为默认属性。在从它们创建实例 bxx 之后分配 key2。检查bxx 是独立对象本身还是只是一个引用。

"use strict";

function a1() {
  this.key1 = "value 1";
}

let a2 = {
  key1: "value 1"
};

let b1new, b1obj, b2new, b2obj;

try {
  b1obj = Object.create(a1);
} catch (e) {
  console.error("Error a1: ", e.message)
}
try {
  b1new = new a1();
} catch (e) {
  console.error("Error a1: ", e.message)
}


try {
  b2obj = Object.create(a2);
} catch (e) {
  console.error("Error a2: ", e.message)
}
try {
  b2new = new a2();
} catch (e) {
  console.error("Error a2: ", e.message)
}

//let b = new a();

a1.key2 = "value 2";
a2.key2 = "value 2";

if (b1obj) {
  console.log("b1obj.key1: ", b1obj.key1);
  console.log("b1obj.key2: ", b1obj.key2);
}
if (b1new) {
  console.log("b1new.key1: ", b1new.key1);
  console.log("b1new.key2: ", b1new.key2);
}
if (b2obj) {
  console.log("b2obj.key1: ", b2obj.key1);
  console.log("b2obj.key2: ", b2obj.key2);
}
if (b2new) {
  console.log("b2new.key1: ", b2new.key1);
  console.log("b2new.key2: ", b2new.key2);
}

输出:

"Error a2: " "a2 is not a constructor"    
"b1obj.key1: " undefined    
"b1obj.key2: " "value 2"    
"b1new.key1: " "value 1"    
"b1new.key2: " undefined    
"b2obj.key1: " "value 1"    
"b2obj.key2: " "value 2"

问题:

  1. 为什么不能在 a2 上使用new
  2. 为什么b1obj.key1undefined
  3. 为什么b2obj.key2 仍然是指父母的财产?

【问题讨论】:

  • 你可以在类上使用new,比如function ClassName(){},而a2只是一个变量
  • Object.create 中使用的对象实际上形成了新对象的原型,而在 new Function() 中,声明的属性/函数不形成原型。
  • 一次问 1 个问题可能更容易,或者至少将您的片段分成单独的片段,只包含您提出的问题。反正newObject.create是不一样的。有很大的不同。
  • @Keith 哇,多么棒的建议和解释。所以根据你的建议,我应该创建3个问题,粘贴相同的代码块并猜猜是什么;我应该得到一个答案'有很大的不同,但不知道是什么'?
  • @AmitShah 是的,因为目前你的问题需要我上下滚动,不断找出你在说什么。如果每个问题和 sn-p 和结果都在一起,那就太好了。它只是让人们更容易提供帮助。例如。第一个问题,我必须找出你是否定义了 a2,然后当你调用 new 时,当然还有问题本身,IOW:上下 3 个位置,1 个问题。最重要的是,还有另外 2 个问题。希望这是有道理的,不要尝试,但对我来说,仅仅因为它的布局,你的问题很难回答。

标签: javascript oop inheritance


【解决方案1】:
  1. new 只能与函数或类一起使用。 当函数以new User(...) 执行时,它会执行以下步骤:

    • 一个新的空对象被创建并分配给this

    • 函数体执行。通常它会修改this,为其添加新属性。

    • 如果没有明确的return语句,则返回this的值。


  1. b1obj.key1undefined 因为Object.create 第一个参数是一个对象,它成为创建对象的原型。在这种情况下,它是a1 函数,它没有分配key1 属性,它只在调用时将key1 分配给它的this

  1. b2obj 具有 a2 对象作为其原型,因此它可以访问其 key2 属性

总结:虽然new 关键字更常用于从现有“模板”创建对象的新实例,但Object.create 更灵活,允许您使用原型,创建属性描述符。例如,您可以创建对象的浅表副本:

let clone = Object.create(Object.getPrototypeOf(obj), 
                          Object.getOwnPropertyDescriptors(obj));

我建议你阅读this关于new关键字和this的一篇关于Object.create和其他原型方法的文章。

UPDATE(关于对象与其原型的关系): 创建新对象后,更改其属性不会影响原型。例如,

let a2 = {
    key2: "some text"
};
let b2 = Object.create(a2);
a2.key2 = "I am a2";
b2.key2 = "I am b2";

alert(a2.key2 + ", " + b2.key2);

将提醒I am a2, I am b2。那是因为b2 有自己的key2 属性。但如果没有,JavaScript 将在其原型中寻找它。可以找到原型继承的详细说明here

【讨论】:

  • Object.create() 在填充诸如 ES6 类之类的东西时也很有用:class A extends B {} -> function A() {}; A.prototype = Object.create(B.prototype, Object.getOwnPropertyDescriptors(A));
  • 谢谢,通过提供的链接后,我发现这个答案更接近我的查询。基本上我理解了其中的区别。现在正在进一步寻找帖子实例/对象创建的另一个相关答案;如果我们更改它们的属性,原始/子对象会发生什么情况……但为此我将创建新帖子。如果您可以提供一些有用的链接,可能会在此之前?
  • @Amit 我添加了一些关于继承的信息。如果回答有用,请采纳
【解决方案2】:

请看下面的答案。

  1. 为什么不能在 a2 上使用 new ?

因为new 关键字只能与constructors/classes 一起使用。在 Javascript 中,functions 可以用作constructors。而a2Object

  1. 为什么 b1obj.key1 未定义?

由于您没有为a1 使用new 关键字,因此不会创建实例并且您将无法使用this 中定义的properties。而Object.create() 将创建一个空对象,其原型设置为a1object 而不是functionfunction 在 JavaScript 中也可以被视为objects

  1. 为什么 b2obj.key2 仍然引用 parent 的属性?

因为你还没有覆盖它。

new 与 Object.create() 之间的真正区别是什么

new 用于constructor 函数,Object.create() 用于继承Objects。此外,Object.create() 可以与functions 一起使用,但随后function 将像正常的object 而不是constructor

【讨论】:

  • 1.所以我不能使用 a2.prototype = {constructor: function(){}} 这样的东西然后我可以在 a2 上使用 new 吗?我认为不,所以问题是构造函数不可见时的形式是什么。它实际上在哪里?所以总体而言; new 将返回执行构造函数的对象的副本。而“Object.create”只会给出一个指向同一对象的对象的新指针。那么如果我在a1.key2 = "value 2"; a2.key2 = "value 2";上方添加新行a1.prototype.key1 = "value 1 new"; a1.prototype.key2 = "value 2 new";会发生什么
猜你喜欢
  • 1970-01-01
  • 2018-02-25
  • 2012-05-08
  • 2017-08-27
  • 2020-10-08
  • 1970-01-01
  • 1970-01-01
  • 2017-10-17
  • 1970-01-01
相关资源
最近更新 更多