如何在JavaScript中没有副作用的情况下操作JSON数据?

时间:2012-05-20 06:34:13

标签: javascript json functional-programming

考虑以下代码

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'。

4 个答案:

答案 0 :(得分:4)

您可能想要look at this answer获取有关“克隆”对象(这非常复杂)的解释,或采取简单的路线并使用J.Resig本人提供的jQuery extend技术上将此克隆代码抽象为简单语法

答案 1 :(得分:2)

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

如果是这种情况,您可能会对this question感兴趣,其中接受的答案使用简单的jQuery来执行此操作。

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

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

这实际上足以用于任何刚被用作关联数组的对象(正如你的那样,并且大多数JSON对象都是如此)。

答案 2 :(得分:1)

您需要克隆该数据对象。

克隆对象的最佳方法是here

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

答案 3 :(得分:1)

要克隆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;});