正如您从我的代码示例中看到的,我想知道为什么下面的东西不能工作。我有一个以对象作为属性的对象(在下面的文本中将它称为支柱)。当我将值赋值给函数中的支柱时,这些值就存在了,因为很明显,它是通过引用传递的,但是我不明白为什么可以引用这个支柱来指向另一个对象。
在将支柱设置为另一个对象的情况下,我只得到空对象,因为它正在启动。我在这里错过了什么?
const person = {
basic: {}
}
function initPersonBasics(b) {
// doesn't work
b = {
firstName: 'John',
lastName: 'Doe'
}
// works
// b.firstName = 'John';
// b.lastName = 'Doe';
}
initPersonBasics(person.basic);
console.log(person);
发布于 2018-04-14 20:00:42
const person = {
basic: {}
}
function initPersonBasics(b) {
b = {
firstName: 'John',
lastName: 'Doe'
};
console.log(b);
}
initPersonBasics(person.basic);
console.log(person);
原因是您正在重新分配b
以指向initPersonBasics
中的另一个对象。但这并没有改变person.basic
指向的位置。
您所做的类似于以下简单代码:
function foo(i) {
i = 42;
}
let j = 10;
foo(j);
你不会指望j
在打电话给foo
后就满42岁了,是吗?
发布于 2018-04-14 20:14:55
在initPersonBasics()
函数中,参数b
的行为类似于局部变量。当函数启动时,它已经用函数的第一个参数(person.basic
)的值初始化了。
但声明
b = {
firstName: 'John',
lastName: 'Doe'
}
在b
中放置一个不同的值;它不会以任何方式改变person.basic
。
正如您已经注意到的,如果不将新对象分配给b
并设置b.firstName
和b.lastName
,则这些值将存储在person.basic
中。这是因为JavaScript赋值不复制对象,而是存储对它们的引用。
有几种方法可以让它像你想的那样工作。您已经发现了其中的一个:将值一个一个地存储在b
的属性中(在函数调用执行期间它是person.basic
的别名)。
另一种选择是使用Object.assign()
function initPersonBasics(b) {
Object.assign(b, {
firstName: 'John',
lastName: 'Doe'
});
}
请注意,它不工作在旧浏览器(甚至在一些较新的浏览器)。仔细检查浏览器兼容性部分。
另一个选项(适用于所有浏览器)是Object.defineProperties()
,但它的语法更冗长:
function initPersonBasics(b) {
Object.defineProperties(b, {
firstName: {
value: 'John',
writable: true,
},
lastName: {
value: 'Doe',
writable: true,
}
});
}
请注意,如果您没有提到属性的writable: true
,它就变成只读的,不能分配给它(并且没有报告错误)。
https://stackoverflow.com/questions/49835495
复制相似问题