2014-11-16 65 views
5

你如何更新整個對象替換對象的值,說:無需更換參考

var x = {a:1} 
function modify(obj) { 
    obj = {b:2} 
} 
modify(x) 
console.log(x) // {a:1} 

但維持基準?我想要在該函數之外修改該對象。

我的具體情況使用lodash.pick我的函數中:

if (whitelist) { 
    obj = _.pick(obj, whitelist) 
} 

我似乎無法找到一個pick功能修改的對象。有沒有辦法做到這一點,或者我需要開始返回對象的副本?

回答

8

delete一切從舊的對象,然後添加新的特性,密鑰 - 通過鍵:

function modify(obj, newObj) { 
 

 
    Object.keys(obj).forEach(function(key) { 
 
    delete obj[key]; 
 
    }); 
 

 
    Object.keys(newObj).forEach(function(key) { 
 
    obj[key] = newObj[key]; 
 
    }); 
 
    
 
} 
 

 
var x = {a:1} 
 
modify(x, {b:42}) 
 
document.write(JSON.stringify(x));

如果你想知道它是否是在根是個好主意實際上,答案是否定的。構建一個新的對象,從函數返回並賦值 - 這是一個非常受歡迎的方式。

+0

這樣做的好方法。我同意你的結論。 – Aravind

+0

我結束了使用lodash'_.cloneDeep'並返回一個新對象,但這是問題的最佳解決方案。並同意這是可怕的做法。 – Garrett

+0

任何人都可以詳細說明爲什麼這是如此可怕嗎?我的場景是,我有一個大型的對象數組,我使用支持「引用對象」來通過它們的ID訪問它們,而不必循環訪問數組。也就是說'modify(referenceObject [objectId],updatedObject);' –

-2

爲什麼修改不能編輯obj引用的對象?

因爲裏面修改當你寫:

obj = {b:2} 

注意OBJ是一個局部變量的函數調用修改。新對象{b:2}已創建,而本地變量obj現在引用此新對象。回想一下,變量x仍然是指{a:1}對象。

如果X是一個全局變量,如果有是名的函數內沒有局部變量,那麼你可以做:

var x = {a:1}; 
function modify() { 
    x = {b:2} 
} 
modify(); 
console.log(x) // {b:2} 

爲什麼上面的代碼工作?

當你調用修改(),它會嘗試,看看它是否有一個局部變量x,因爲它找不到一個,它會查找作用域鏈。尋找這個函數調用的下一個範圍是全局範圍,當然,我們有一個x變量。因此,此全局變量x的值現在設置。

+0

理想地,函數修改傳入的變量。看起來我不得不返回對象而不是修改它。 – Garrett

+0

但是,如果在函數modify中使用「obj.a = 3」而不是「obj = {b:2}」,則x的值將會改變。您如何解釋? –

+0

@plbsam:這是因爲當你寫obj.a = 3時,Javascript首先在obj中查找屬性a。當你調用函數modify(x)時,函數modify的局部變量obj被設置爲x,所以obj指向x指向的同一個對象。因此,當你寫obj.a = 3;它設置由x指向的同一對象的屬性。合理? – Aravind

1

你可以做到這一點(不是你想要什麼),如果你包裝你的對象,並改變修改這樣的功能,

var wrapper = {}; 
wrapper.x = {a:1}; 
function modify(obj, key) { 
    obj[key] = {b:2}; 
} 
modify(wrapper, 'x'); 
console.log(wrapper.x); // {b:2} 
0

我有這個問題。經過一番研究,我選擇將objectTwo轉換爲JSON字符串,然後用解析後的版本替換objectOne。換句話說:

var mObjectOne = { ExampleProperty: 10 }; 
var mObjectTwo = { ExampleProperty: 15 }; 

// I wanted mObjectOne to hold the same data as mObjectTwo, but keep a separate reference 
var mObjectTwoAsJSON = JSON.stringify(mObjectTwo); 
mObjectOne = JSON.parse(mObjectTwoAsJSON); 

// Now the references are still different, as desired, but the object data has been updated. 

謝謝,