0

考虑以下代码

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

4 回答 4

4

您可能想查看这个答案以了解有关“克隆”对象(这真的很复杂)的解释,或者采取简单的方法并使用J.Resig 自己提供的jQuery 扩展,它在技术上将此克隆代码抽象为一个简单的句法

于 2012-05-20T06:39:26.790 回答
2

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

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

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

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

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

于 2012-05-20T06:39:00.733 回答
1

您需要克隆该数据对象。

克隆对象的最佳方法是什么在这里回答

// jQuery
newData = $.extend({}, data);
于 2012-05-20T06:39:33.420 回答
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;});
于 2012-05-20T06:55:29.010 回答