我有一个描述我的问题的功能:
function testingFunc(value) {
var temp = value;
console.log("temp before: " + JSON.stringify(temp));
console.log("arrayTest before: " + JSON.stringify(arrayTest));
temp.unshift(123);
console.log("temp after unshift: " + JSON.stringify(temp));
console.log("arrayTest after unshift: " + JSON.stringify(arrayTest));
temp.push(456);
console.log("temp after push: " + JSON.stringify(temp));
console.log("arrayTest after push: " + JSON.stringify(arrayTest));
temp.shift();
console.log("temp after shift: " + JSON.stringify(temp));
console.log("arrayTest after shift: " + JSON.stringify(arrayTest));
temp.pop();
console.log("temp after pop: " + JSON.stringify(temp));
console.log("arrayTest after pop: " + JSON.stringify(arrayTest));
return temp;
}
var arrayTest = [1,2,3,4,5];
var arrayTestTwo;
arrayTestTwo = testingFunc(arrayTest);
console.log("arrayTest after testingFunc: " + JSON.stringify(arrayTest));
console.log("arrayTestTwo: " + JSON.stringify(arrayTestTwo));

正如您所看到的,如果使用arrayTest
,temp
,push
和unshift
进行pop
更改,shift
也会发生变化它的数据。
但我希望这些功能仅适用于temp
并忽略arrayTest
。
有可能吗?还可以使用包含对象的函数吗?
为什么会发生这种情况?
答案 0 :(得分:5)
将数组赋值给变量(或将其作为参数传递给函数)时,只将引用存储到该数组中。如果两个或多个变量引用同一个数组,那么对一个变量进行更改也会影响所有其他变量:
var original = [];
var modified = original;
console.log(original, modified); // [] []
modified.push(1, 2, 3);
console.log(original, modified); // [1,2,3] [1,2,3]

解决此问题的方法是制作数组的副本。要制作数组副本,只需拨打array.slice()
:
var original = [];
var modified = original.slice();
console.log(original, modified); // [] []
modified.push(1, 2, 3);
console.log(original, modified); // [] [1,2,3]

答案 1 :(得分:2)
您应该查看以下概念:
value
和reference
之间的区别:Is JavaScript a pass-by-reference or pass-by-value language? 基本上primitives
始终为passed by value
,object
始终为passed by reference
。
// Using Primitives:
var a = "Hello";
var b = a;
b += " World";
console.log('a', a);
console.log('b', b);
//Using References
var a = { hello: "Hello" };
var b = a;
b.hello += ' World';
console.log('a', a);
console.log('b', b);
// As you can see, because b is just a reference to a, editing b you're editing a too.

所以,按照我上面所说的,你需要复制那些对象:
var a = { hello: 'Hello' };
var b = Object.assign(Object.create(null), a);
//Object.assign is es-next, you need for a polyfill
b.hello += ' World';
console.log('a', a);
console.log('b', b);

使shallow copy of arrays
更容易,因为有许多原生方法:Array.prototype.map, Array.prototype.reduce, Array.prototype.filter, Array.prototype.concat, etc...
;
答案 2 :(得分:0)
与任何对象一样,数组通过引用传递。这意味着你的temp是别名到 arrayTest 。如果您不想在函数外部修改数组,请创建一个副本。
如果你坚持使用.push(),. pop(),. shift()和.unshift(),那么你需要的只是浅拷贝,因为它们不会改变任何数组的元素,甚至如果它们本身就是引用(非原始的)。
对于数组浅拷贝,请使用.slice()
阅读说明将有助于: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
答案 3 :(得分:0)
有一些流行的库来规避Arrays,Objects的问题。等,例如来自Facebook的immutable.js。