我对javascript开发相当陌生,仍在学习概念。我有一个关于点差"运算符"(...
(的问题。 它可以用作类似继承的机制,还是有副作用,应该让我避免这种情况?
例
const A = {
prop1: "value1",
prop2: function() {return this.prop1}
}
const B = {
...A,
prop1: "updated_value1",
prop3: "value3"
}
这里可以看到 B 是从 A 继承的,A.prop2()
返回value1
,并且B.prop2()
返回updated_value1
从任何继承的对象中得到期望。
这有效吗?
您发布的代码按预期工作,因为 A 中的属性将复制到 B。但是,这不是继承的示例,它只是一个浅层副本。
在您的示例中,所有属性都是基元,请考虑如果我们添加对 A 的引用会发生什么:
const A = {
prop1: "value1",
prop2: function() {return this.prop1},
obj: { value: 1 }
}
const B = {
...A,
prop1: "updated_value1",
prop3: "value3"
}
现在,改变A.obj.value
也会修改B.obj.value
这基本上会使所有B与A共享他们的obj
以及他们之间。这在某些情况下可能很有用,但它并不完全是继承。
对于继承,最好使用"Javascript类">
在您的情况下,我倾向于使用对象分配,因为出错的情况更少:
const A = {
prop1: "value1",
prop2: function() {return this.prop1}
}
cont B = Object.assign(A, {
prop1: "updated_value1",
prop3: "value3"
});
但这仍然不是真正的遗产。
它可能看起来像继承,但实际上你在那里定义的所有内容都是:
const A = {
prop1: "value1",
prop2: function() {return this.prop1}
}
const B = {
prop1: "value1",
prop2: function() {return this.prop1},
prop1: "updated_value1",
prop3: "value3"
}
实质上,您正在覆盖为对象 B 定义的 2 行成员。 它不是继承,因为成员的定义将由对象 B 拥有,而不是例如 B 的原型。当引用 B.prop1 时,引擎将不必查找属性的原型,如果您使用原型,继承将执行此操作
你不能真正称之为固有。这是一个合并。通过写这个
const B = {
...A,
prop1: "updated_value1",
prop3: "value3"
}
来自 A 的props1
将被来自 B 的prop1
覆盖。所以是的,B.prop2()
会回来updated_value1
,这是完全公平的。
我不会称之为继承。将 spread 运算符与 object 一起使用类似于使用 Object.assign((。此方法的作用是将所有可枚举的自己的属性的值从一个或多个源对象复制到目标对象。 请参阅文档
{...A} 只是从"A"创建所有键值的副本,并将其设置为"B"。 然后,将"B"的属性 prop1 更新为 updated_value1。"A"保持不变。这是完全有效的