如何在 JavaScript 中操作 JSON 数据而不会产生副作用

How can I manipulate JSON data without side effects in JavaScript?

本文关键字:副作用 数据 JSON JavaScript 操作      更新时间:2023-09-26

>请考虑以下代码

var myData = {name: 'John'};
function fixName(data) {
    var newData = data;
    newData.name = 'Mike';
    return newData;
}
var myData2 = fixName(myData);
console.log(myData2.name);
console.log(myData.name);

"Mike"被打印了两次,因为在我的函数中,newData和myData指向同一件事。 如何更改我的函数,使其对 myData 没有副作用? 这意味着程序应该打印"Mike",然后打印"John"。

你可能想看看这个答案,以获得关于"克隆"一个对象的解释(这真的很复杂(,或者采取简单的路线并使用J.Resig自己提供的jQuery extend,它在技术上将此克隆代码抽象为简单的语法。

所以基本上你想创建一个对象的副本而不是获取引用?

如果是这种情况,您可能会对这个问题感兴趣,其中接受的答案使用简单的jQuery来做到这一点。

如果像我一样,你不想使用 jQuery,你可以使用循环来获取基本副本:

var myData2 = {};
for( var x in myData) if( myData.hasOwnProperty(x)) myData2[x] = myData[x];
// Copied!

对于任何仅用作关联数组的对象(就像您的对象一样,以及大多数 JSON 对象一样(,这实际上已经足够了。

您需要克隆该数据对象。

克隆对象的最佳方法是什么,请在此处回答

// jQuery
newData = $.extend({}, data);

要克隆myData,您可以使用JSON.parse(JSON.stringify(myData))

var myData = {name: 'John'};
function fixName(data) {
    var newData = data;
    newData.name = 'Mike';
    return newData;
}
var myData2 = fixName( JSON.parse(JSON.stringify(myData)) );
console.log(myData2.name); //=> Mike
console.log(myData.name);  //=> John

顺便说一下,这也将克隆嵌套对象。

它创建一个函数可能是一个想法:

function cloneObj(obj,reviver){
  return JSON.parse(JSON.stringify(obj),reviver);
}

reviver可用于操作对象中的数据,在您的情况下,这将使fixName过时。

var myData2 = cloneObj(myData, function(k,v){return k === 'name' ? 'Mike' : v;});