我想了解关键字new
和Object.create()
解释:
a1
为function
而a2
为object
a1
& a2
将key1
作为默认属性。在从它们创建实例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"
问题:
new
b1obj.key1
是undefined
?b2obj.key2
仍然指父母的财产?答案 0 :(得分:2)
请参阅以下答案。
- 为什么不能在a2上使用new?
醇>
因为new
关键字只能与constructors/classes
一起使用。在Javascript中functions
可以用作constructors
。 a2
是Object
- 为什么b1obj.key1未定义?
醇>
由于您未使用new
a1
关键字,因此不会创建实例,并且您无法使用{{1}中定义的properties
}}。 this
将创建一个空对象,其原型设置为Object.create()
a1
而不是object
(function
也可以视为function
的JavaScript)
- 为什么b2obj.key2仍然指父母的财产?
醇>
因为你没有覆盖它。
new与Object.create()
之间的真正区别是什么?
objects
用于new
个函数,constructor
用于继承Object.create()
。此外,Objects
可以与Object.create()
一起使用,但functions
将表现得像普通function
而不是object
。
答案 1 :(得分:2)
new
只能用于函数或类。
当函数执行为new User(...)
时,它执行以下步骤:
创建一个新的空对象并将其分配给this
。
函数体执行。通常它会修改this
,为其添加新属性。
如果没有明确的return
语句,则会返回this
的值。
b1obj.key1
是undefined
,因为Object.create
第一个参数是一个对象,它成为创建对象的原型。在这种情况下,a1
函数没有分配key1
属性,只有key1
才会调用this
。b2obj
将a2
对象作为其原型,因此可以访问其key2
属性 总结:虽然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