如何在javascript中使用本地数组进行推送,取消移位,弹出和转换?

时间:2016-10-10 21:01:45

标签: javascript arrays function

我有一个描述我的问题的功能:



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));




正如您所看到的,如果使用arrayTesttemppushunshift进行pop更改,shift也会发生变化它的数据。

但我希望这些功能仅适用于temp并忽略arrayTest

有可能吗?还可以使用包含对象的函数吗?

为什么会发生这种情况?

4 个答案:

答案 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)

您应该查看以下概念:

  1. 纯函数:http://www.nicoespeon.com/en/2015/01/pure-functions-javascript/
  2. 不可变模式:https://www.sitepoint.com/immutability-javascript/
  3. valuereference之间的区别:Is JavaScript a pass-by-reference or pass-by-value language?
  4. 如何制作浅色副本或深层副本:What is the difference between a shallow copy and a deep copy with JavaScript arrays?
  5. 基本上primitives始终为passed by valueobject始终为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