对象的对象作为函数参数

时间:2018-04-14 19:44:42

标签: javascript

从我的代码示例中可以看出,我想知道为什么以下的东西不起作用。 我有一个对象作为属性(将在下面的文本中称为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);

2 个答案:

答案 0 :(得分:2)

initPersonBasics()函数中,参数b的行为类似于局部变量。当函数启动时,它已经使用函数的第一个参数(person.basic)的值进行初始化。

但声明

b = {
    firstName: 'John',
    lastName: 'Doe'
}

b中添加不同的值;它不会以任何方式改变person.basic

正如您已经指出的那样,如果您没有将新对象分配给b并设置b.firstNameb.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,对吗?