2016-12-14 68 views
0

我有这样的代码:Object.assign() - 怪异的行为需要解释

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} <-- !

那么这里发生了什么?

+1

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

回答

2

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

options = Object.assign(options, passedOptions); 

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

第二个函数传递一个新构造的空对象作为第一个参数,这意味着以options传递的对象不会被修改。修改的对象被分配回options,但因为它只是一个函数参数,不会更改调用环境中的引用。如果您想这样做,则必须返回该值并将其分配到呼叫环境中。

2

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


如果你的困惑是为什么分配没有改变opts,这是因为分配给该参数不具有对功能之外的任何内容有任何影响。例如: -

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

这是因为foo(x)读取价值x,并将其传递到fooax之间没有联系,a的值最初来自x

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