2016-12-14 70 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