从我的代码示例中可以看出,我想知道为什么以下的东西不起作用。 我有一个对象作为属性(将在下面的文本中称为prop)。 当我将值分配给函数中的prop时,那些值就在那里,因为很明显它是通过引用传递的,但是我不明白为什么可以引用prop来指向另一个对象。
在将prop设置为另一个对象的情况下,我只是获取空对象,就像它在开始时一样。 我在这里缺少什么?
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);
答案 0 :(得分:2)
在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'
});
}
请注意,它不适用于较旧的浏览器(甚至在较新的浏览器中)。仔细检查Browser compatibility部分。
另一个选项(适用于所有浏览器)是Object.defineProperties()
但其语法更详细:
function initPersonBasics(b) {
Object.defineProperties(b, {
firstName: {
value: 'John',
writable: true,
},
lastName: {
value: 'Doe',
writable: true,
}
});
}
请注意,如果您没有提及writable: true
某个属性,它将变为只读且无法分配(并且不会报告错误)。
答案 1 :(得分:1)
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,对吗?