Javascript 按值复制数组

Javascript 按值复制数组,javascript,arrays,Javascript,Arrays,将JavaScript中的数组复制到另一个数组时: var arr1 = ['a','b','c']; var arr2 = arr1; arr2.push('d'); //Now, arr1 = ['a','b','c','d'] 我意识到arr2指的是与arr1相同的数组,而不是一个新的独立数组。如何复制阵列以获得两个独立的阵列?无需jQuery var arr2 = arr1.slice() 这将从起始位置0到阵列的末端复制阵列 重要的是要注意,它将按原语类型(字符串、数字等)的预期

将JavaScript中的数组复制到另一个数组时:

var arr1 = ['a','b','c'];
var arr2 = arr1;
arr2.push('d');  //Now, arr1 = ['a','b','c','d']

我意识到
arr2
指的是与
arr1
相同的数组,而不是一个新的独立数组。如何复制阵列以获得两个独立的阵列?

无需jQuery

var arr2 = arr1.slice()
这将从起始位置
0
到阵列的末端复制阵列

重要的是要注意,它将按原语类型(字符串、数字等)的预期工作,并解释引用类型的预期行为

如果您有一个引用类型数组,比如类型
对象
。将复制数组,但两个数组都将包含对相同
对象的引用。因此,在这种情况下,数组似乎是通过引用复制的,即使数组实际上是复制的。

使用以下方法:

让oldArray=[1,2,3,4,5];
设newArray=oldArray.slice();

log({newArray})如果要创建对象或数组的新副本,必须显式复制对象的属性或数组的元素,例如:

var arr1 = ['a','b','c'];
var arr2 = [];

for (var i=0; i < arr1.length; i++) {
   arr2[i] = arr1[i];
}
var arr1=['a','b','c'];
var arr2=[];
对于(变量i=0;i
您可以在Google上搜索有关不可变原语值和可变对象引用的更多信息。

is的另一种选择,它有两种使用方式。其中第一个可能更具可读性,因为预期行为非常清楚:

var array2 = [].concat(array1);
第二种方法是:

var array2 = array1.concat();
科恩(在评论中)指出后一种方法

其工作方式是
concat
方法创建一个新数组,该数组由调用它的对象中的元素组成,后跟作为参数传递给它的任何数组的元素。因此,当没有传递任何参数时,它只是复制数组

Lee Penkman也在评论中指出,如果
array1
有可能是
undefined
,则可以返回空数组,如下所示:

var array2 = [].concat(array1 || []);
var arr1 = [1, 2, 3];
console.log(Array.from(arr1)); // Logs: [1, 2, 3]
或者,对于第二种方法:

var array2 = (array1 || []).concat();

请注意,您也可以使用
slice
var array2=(array1 | |[]).slice()执行此操作

当使用简单的数据类型(如number或string)时,上面提到的一些方法工作得很好,但当数组包含其他对象时,这些方法会失败。当我们试图将任何对象从一个数组传递到另一个数组时,它作为引用传递,而不是对象

在JavaScript文件中添加以下代码:

Object.prototype.clone = function() {
    var newObj = (this instanceof Array) ? [] : {};
    for (i in this) {
        if (i == 'clone') 
            continue;
        if (this[i] && typeof this[i] == "object") {
            newObj[i] = this[i].clone();
        } 
        else 
            newObj[i] = this[i]
    } return newObj;
};
并且简单地使用

var arr1 = ['val_1','val_2','val_3'];
var arr2 = arr1.clone()
它会起作用。

这里有一个变体:

var arr1=['a', 'b', 'c'];
var arr2=eval(arr1.toSource());
arr2.push('d');
console.log('arr1: '+arr1+'\narr2: '+arr2);
/*
 *  arr1: a,b,c
 *  arr2: a,b,c,d
 */

添加到array.slice()的解决方案中请注意,如果您有多维数组,子数组将通过引用进行复制。 您可以分别循环和切片()每个子数组

var arr = [[1,1,1],[2,2,2],[3,3,3]];
var arr2 = arr.slice();

arr2[0][1] = 55;
console.log(arr2[0][1]);
console.log(arr[0][1]);

function arrCpy(arrSrc, arrDis){
 for(elm in arrSrc){
  arrDis.push(arrSrc[elm].slice());
}
}

var arr3=[];
arrCpy(arr,arr3);

arr3[1][1] = 77;

console.log(arr3[1][1]);
console.log(arr[1][1]);

同样的事情也发生在对象数组中,它们将通过引用进行复制,您必须手动复制它们

var newArray = JSON.parse(JSON.stringify(orgArray));
这将创建一个与第一个深度副本无关的新深度副本(不是浅层副本)


此外,这显然不会克隆事件和函数,但好处是可以在一行中完成,并且可以用于任何类型的对象(数组、字符串、数字、对象…)

在Javascript中,深度复制技术取决于数组中的元素。让我们从这里开始

三类元素 元素可以是:文字值、文字结构或原型

// Literal values (type1)
const booleanLiteral = true;
const numberLiteral = 1;
const stringLiteral = 'true';

// Literal structures (type2)
const arrayLiteral = [];
const objectLiteral = {};

// Prototypes (type3)
const booleanPrototype = new Bool(true);
const numberPrototype = new Number(1);
const stringPrototype = new String('true');
const arrayPrototype = new Array();
const objectPrototype = new Object(); // or `new function () {}`
根据这些元素,我们可以创建三种类型的数组

// 1) Array of literal-values (boolean, number, string) 
const type1 = [true, 1, "true"];

// 2) Array of literal-structures (array, object)
const type2 = [[], {}];

// 3) Array of prototype-objects (function)
const type3 = [function () {}, function () {}];
深度复制技术取决于三种阵列类型 根据数组中元素的类型,我们可以使用各种技术进行深度复制

  • 文字值数组(类型1)
    […myArray]
    myArray.splice(0)
    myArray.slice()
    ,和
    myArray.concat()
    技术只能用于使用文字值(布尔值、数字和字符串)深度复制数组;其中,扩展运算符
    […myArray]
    具有最佳性能()

  • 文字值数组(类型1)和文字结构数组(类型2)
    JSON.parse(JSON.stringify(myArray))
    技术可用于深度复制文字值(布尔值、数字、字符串)和文字结构(数组、对象),但不能复制原型对象

  • 所有数组(类型1、类型2、类型3)
    jQuery
    $.extend(myArray)
    技术可用于深度复制所有数组类型。库与
    $.extend()
    类似,并提供类似的深度复制函数,但性能较低。更令人惊讶的是,
    $.extend()
    JSON.parse(JSON.stringify(myArray))
    技术具有更高的性能。
    对于那些不愿使用第三方库(如jQuery)的开发人员,您可以使用以下自定义函数:;它的性能高于$.extend,并且深度复制所有阵列

所以要回答这个问题。。。 问题

var arr1 = ['a','b','c'];
var arr2 = arr1;
我意识到arr2和arr1是同一个数组,而不是一个数组 新的独立阵列。如何复制数组以获得两个 独立阵列

回答

由于
arr1
是一个文本值(布尔值、数字或字符串)数组,因此可以使用上面讨论的任何深度复制技术,其中扩展运算符
具有最高的性能

// Highest performance for deep copying literal values
arr2 = [...arr1];

// Any of these techniques will deep copy literal values as well,
//   but with lower performance.
arr2 = arr1.slice();
arr2 = arr1.splice(0);
arr2 = arr1.concat();
arr2 = JSON.parse(JSON.stringify(arr1));
arr2 = $.extend(true, [], arr1); // jQuery.js needed
arr2 = _.extend(arr1); // Underscore.js needed
arr2 = _.cloneDeep(arr1); // Lo-dash.js needed
arr2 = copy(arr1); // Custom-function needed - as provided above

在我的特殊情况下,我需要确保阵列保持完整,因此这对我有效:

// Empty array
arr1.length = 0;
// Add items from source array to target array
for (var i = 0; i < arr2.length; i++) {
    arr1.push(arr2[i]);
}
//空数组
arr1.length=0;
//将项目从源阵列添加到目标阵列
对于(变量i=0;i
复制多维数组/对象:

function deepCopy(obj) {
   if (Object.prototype.toString.call(obj) === '[object Array]') {
      var out = [], i = 0, len = obj.length;
      for ( ; i < len; i++ ) {
         out[i] = arguments.callee(obj[i]);
      }
      return out;
   }
   if (typeof obj === 'object') {
      var out = {}, i;
      for ( i in obj ) {
         out[i] = arguments.callee(obj[i]);
      }
      return out;
   }
   return obj;
}
功能深度复制(obj){
if(Object.prototype.toString.call(obj)='[Object Array]'){
var out=[],i=0,len=obj.length;
对于(;ivar arr1 = [1, 2, 3];
console.log(Array.from(arr1)); // Logs: [1, 2, 3]
function identity(param)
{
    return param;
}

var arr1 = [1, 2, 3],
    clone = arr1.map(identity);
var parts = ['shoulders', 'knees'];
var lyrics = ['head', ...parts, 'and', 'toes'];
var arr2 = [...arr1];
var arr2 = $.extend(true, [], arr1);
var arr = [1, 2, 3, 4, 5];
 function newArr(arr) {
      var i=0, res = [];
      while(i<arr.length){
       res.push(arr[i]);
        i++;
       }
   return res;
 }
var arr2 = arr.slice(); // make a copy of the original array
var arr2 = arr.concat();
var arr2 = JSON.parse(JSON.stringify(arr));
const arr2 = Array.from(arr);
const arr2 = [...arr];
var arr=[2,3,4,5];
var copyArr=[...arr];
cloneArray(arr) {
    return arr.map(x => ({ ...x }));
}
arr2 = [...arr1];
new_array = old_array.slice()
new_array = old_array.map((elem) => elem)
const new_array = new Array(...old_array);
var new_array = JSON.parse(JSON.stringify(old_array));
let a = [1,2,3];
let b = Array.from(a); 
let b = [...a];
let b = new Array(...a); 
let b = a.slice(); 
let b = a.map(e => e);
a.push(5); 
let arr = [1,2,3,4,5];
let arrCopy = [...arr]; 
let arrCopy = arr.slice(); 
let arrCopy = [].concat(arr);
arrCopy[1] = 'adding new value this way will unreference';
JSON.parse(JSON.stringify( originalObject ));