【问题标题】:Object.assign() - weird behaviour need explanationObject.assign() - 奇怪的行为需要解释
【发布时间】:2017-04-30 04:39:24
【问题描述】:

我有这个代码:

function margeOptions(options, passedOptions) {
  options = Object.assign(options, passedOptions); 
}

let passedOpts = {a: true};
let opts = {a: false};

margeOptions(opts, passedOpts); 
console.log(opts); // as expected returns {a: true} 

但是当我稍微改变一下功能时,像这样:

function margeOptions(options, passedOptions) {
  options = Object.assign({}, options, passedOptions); 
}

let passedOpts = {a: true};
let opts = {a: false};

margeOptions(opts, passedOpts); 
console.log(opts); // this time returns {a: false} <-- !

那么这里到底发生了什么?

【问题讨论】:

  • formal_parameter = 在函数中不会以任何方式影响实际参数

标签: javascript object assign


【解决方案1】:

Object.assign 设置对象的属性作为第一个参数;它还返回相同的对象。因此,在您的第一个示例中,由于您将 option 作为第一个参数传递,它会使用新的/更新的属性进行更新。在您的第二个示例中,您没有将它作为第一个参数传递,它只是要从中读取属性的“源”对象之一,因此不会更新。


如果您的困惑是赋值 没有更改opts 的原因,那是因为赋值给参数不会对函数之外的任何内容产生任何影响。例如:

function foo(a) {
    a = 42;
}
var x = 67;
foo(x);
console.log(x); // Still 67

这是因为foo(x) 读取x 的值 并将其传递给foo。除了a的值最初来自x之外,a和x之间没有任何联系。

与opts/options完全一样。 mergeOptions(opts, passedOptions) 读取opts 的值,这是一个对象引用,并将该值传递给mergeOptions。该值与opts 之间没有持续的联系。对象引用指向对象,而不是变量opts。

【讨论】:

    【解决方案2】:

    Object.assign() 函数修改第一个对象参数的内容。因此在第一个函数中:

    options = Object.assign(options, passedOptions); 
    

    您的代码有效,因为options 是第一个参数。请注意,分配回options 参数没有任何效果,或者至少没有有用的效果。它将Object.assign 的返回值分配给options 变量,但这是它已经拥有的值。

    第二个函数传入一个新构造的空对象作为第一个参数,也就是说以options传递的对象不会被修改。修改后的对象被分配回options,但因为它只是一个函数参数,不会改变调用环境中的引用。如果你想这样做,你必须返回值并在调用环境中分配它。

    【讨论】:

      猜你喜欢
      • 2011-06-13
      • 2017-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-08
      • 1970-01-01
      相关资源
      最近更新 更多