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

时间:2017-12-15 11:08:06

标签: javascript oop inheritance

我想了解关键字newObject.create()

之间的真正区别

解释:

  • a1functiona2object
  • a1& a2key1作为默认属性。在从它们创建实例key2之后,将分配bxx。检查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仍然指父母的财产?

2 个答案:

答案 0 :(得分:2)

请参阅以下答案。

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

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

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

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

  
      
  1. 为什么b2obj.key2仍然指父母的财产?
  2.   

因为你没有覆盖它。

  

new与Object.create()

之间的真正区别是什么?

objects用于new个函数,constructor用于继承Object.create()。此外,Objects可以与Object.create()一起使用,但functions将表现得像普通function而不是object

答案 1 :(得分:2)

  1. new只能用于函数或类。 当函数执行为new User(...)时,它执行以下步骤:

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

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

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

    1. b1obj.key1undefined,因为Object.create第一个参数是一个对象,它成为创建对象的原型。在这种情况下,a1函数没有分配key1属性,只有key1才会调用this
      1. b2obja2对象作为其原型,因此可以访问其key2属性
      2. 总结:虽然new关键字更常用于从现有“模板”创建对象的新实例,Object.create更灵活,可让您工作使用原型,创建属性描述符。例如,您可以创建对象的浅表副本:

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

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

        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

        的详细说明