精华内容
下载资源
问答
  • JavaScript 拷贝数组

    2021-06-09 23:18:10
    我们可以使用数组的concat( )方法、splice( )方法、slice( )方法或map( )方法来拷贝一个数组。 (1)使用concat( )方法 示例:

    我们可以使用数组的concat( )方法、splice( )方法、slice( )方法或map( )方法来拷贝一个数组。

    (1)使用concat( )方法

    示例:

            var arr1 = [1,2,3,4,5,6];
            var arr2 = [].concat(arr1);
            console.log(arr1,arr2);

    控制台输出:

    注意:concat( )方法不会改变原数组。

    (2)使用splice( )方法

    示例:

            var arr1 = [1,2,3,4,5,6];
            var arr2 = arr1.splice(0);
            console.log(arr1,arr2);

    控制台输出:

    注意:splice( )方法会改变原数组。

    (3)使用slice( )方法

    示例:

            var arr1 = [1,2,3,4,5,6];
            var arr2 = arr1.slice(0);
            console.log(arr1,arr2);

    控制台输出:

    注意:slice( )方法不会改变原数组。

    (4)使用map( )方法

    示例:

            var arr1 = [1,2,3,4,5,6];
            var arr2 = arr1.map(function(currentValue){
                return currentValue;
            })
            console.log(arr1,arr2);

    控制台输出:

    注意:map( )方法不会改变原数组。

    展开全文
  • JavaScript中我们经常会遇到拷贝数组的场景,但是都有哪些方式能够来实现呢,我们不妨来梳理一下。 1、扩展运算符(浅拷贝) 自从ES6出现以来,这已经成为最流行的方法。它是一个很简单的语法,但是当你在使用类似...
    JavaScript中我们经常会遇到拷贝数组的场景,但是都有哪些方式能够来实现呢,我们不妨来梳理一下。

    十种一步拷贝数组的方法

    1、扩展运算符(浅拷贝)

    自从ES6出现以来,这已经成为最流行的方法。它是一个很简单的语法,但是当你在使用类似于React和Redux这类库时,你会发现它是非常非常有用的。

    numbers = [1, 2, 3];
    numbersCopy = [...numbers];

    这个方法不能有效的拷贝多维数组。数组/对象值的拷贝是通过引用而不是值复制。

    // ?
    numbersCopy.push(4);
    console.log(numbers, numbersCopy);
    // [1, 2, 3] and [1, 2, 3, 4]
    // 只修改了我们希望修改的,原数组不受影响
    

    // ?
    nestedNumbers = [[1], [2]];
    numbersCopy = […nestedNumbers];
    numbersCopy[0].push(300);
    console.log(nestedNumbers, numbersCopy);
    // [[1, 300], [2]]
    // [[1, 300], [2]]
    // 由于公用引用,所以两个数组都被修改了,这是我们不希望的

    2、for()循环(浅拷贝)

    考虑到函数式编程变得越来越流行,我认为这种方法可能是最不受欢迎的。

    
    numbers = [1, 2, 3];
    numbersCopy = [];
    for (i = 0; i < numbers.length; i++) {
      numbersCopy[i] = numbers[i];
    }
    

    这个方法不能有效的拷贝多维数组。因为我们使用的是=运算符,它在处理数组/对象值的拷贝时通过引用而不是值复制。

    // ?
    numbersCopy.push(4);
    console.log(numbers, numbersCopy);
    // [1, 2, 3] and [1, 2, 3, 4]
    

    // ?
    nestedNumbers = [[1], [2]];
    numbersCopy = [];
    for (i = 0; i < nestedNumbers.length; i++) {
    numbersCopy[i] = nestedNumbers[i];
    }
    numbersCopy[0].push(300);
    console.log(nestedNumbers, numbersCopy);
    // [[1, 300], [2]]
    // [[1, 300], [2]]
    // 由于公用引用,所以两个数组都被修改了,这是我们不希望的

    3、while()循环(浅拷贝)

    for() 类似。

    numbers = [1, 2, 3];
    numbersCopy = [];
    i = -1;
    while (++i < numbers.length) {
      numbersCopy[i] = numbers[i];
    }

    4、Array.map(浅拷贝)

    上面的forwhile都是很“古老”的方式,让我们继续回到当前,我们会发现map方法。map源于数学,是将一个集合转换成另一种集合,同时保留结构的概念。

    在英语中,它意味着Array.map 每次返回相同长度的数组。

    numbers = [1, 2, 3];
    double = (x) => x * 2;
    

    numbers.map(double);

    当我们使用map方法时,需要给出一个callback函数用于处理当前的数组,并返回一个新的数组元素。

    和拷贝数组有什么关系呢?

    当我们想要复制一个数组的时候,只需要在mapcallback函数中直接返回原数组的元素即可。

    numbers = [1, 2, 3];
    numbersCopy = numbers.map((x) => x);

    如果你想更数学化一点,(x) => x叫做恒等式。它返回给定的任何参数。

    identity = (x) => x;
    numbers.map(identity);
    // [1, 2, 3]

    同样的,处理对象和数组的时候是引用而不是值复制。

    5、Array.filter(浅拷贝)

    Array.filter方法同样会返回一个新数组,但是并不一定是返回同样长度的,这和我们的过滤条件有关。

    [1, 2, 3].filter((x) => x % 2 === 0)
    // [2]

    当我们的过滤条件总是true时,就可以用来实现拷贝。

    numbers = [1, 2, 3];
    numbersCopy = numbers.filter(() => true);
    // [1, 2, 3]

    同样的,处理对象和数组的时候是引用而不是值复制。

    6、Array.reduce(浅拷贝)

    其实用reduce来拷贝数组并没有展示出它的实际功能,但是我们还是要将其能够拷贝数组的能力说一下的

    numbers = [1, 2, 3];
    numbersCopy = numbers.reduce((newArray, element) => {
      newArray.push(element);
      return newArray;
    }, []);

    reduce() 方法对数组中的每个元素执行一个由您提供的reducer函数,将其结果汇总为单个返回值。

    上面我们的例子中初始值是一个空数组,我们在遍历原数组的时候来填充这个空数组。该数组必须要从下一个迭代函数的执行后被返回出来。

    同样的,处理对象和数组的时候是引用而不是值复制。

    7、Array.slice(浅拷贝)

    slice 方法根据我们指定的start、end的index从原数组中返回一个浅拷贝的数组。

    [1, 2, 3, 4, 5].slice(0, 3);
    // [1, 2, 3]
    // Starts at index 0, stops at index 3
    

    // 当不给定参数时,就返回了原数组的拷贝
    numbers = [1, 2, 3, 4, 5];
    numbersCopy = numbers.slice();
    // [1, 2, 3, 4, 5]

    同样的,处理对象和数组的时候是引用而不是值复制。

    8、JSON.parse & JSON.stringify(深拷贝)

    JSON.stringify将一个对象转成字符串;
    JSON.parse将转成的字符串转回对象。

    将它们组合起来可以将对象转换成字符串,然后反转这个过程来创建一个全新的数据结构。

    nestedNumbers = [[1], [2]];
    numbersCopy = JSON.parse(
      JSON.stringify(nestedNumbers)
    );
    numbersCopy[0].push(300);
    console.log(nestedNumbers, numbersCopy);
    // [[1], [2]]
    // [[1, 300], [2]]
    // These two arrays are completely separate!

    这个可以安全地拷贝深度嵌套的对象/数组

    几种特殊情况

    1、如果obj里面有时间对象,则JSON.stringify后再JSON.parse的结果,时间将只是字符串的形式。而不是时间对象;

    var test = {
      name: 'a',
      date: [new Date(1536627600000), new Date(1540047600000)],
    };
    

    let b;
    b = JSON.parse(JSON.stringify(test))
    console.log(b)

    2、如果obj里有RegExp、Error对象,则序列化的结果将只得到空对象;

    const test = {
      name: 'a',
      date: new RegExp('\\w+'),
    };
    // debugger
    const copyed = JSON.parse(JSON.stringify(test));
    test.name = 'test'
    console.log('ddd', test, copyed)

    3、如果obj里有函数,undefined,则序列化的结果会把函数或 undefined丢失;

    const test = {
      name: 'a',
      date: function hehe() {
        console.log('fff')
      },
    };
    // debugger
    const copyed = JSON.parse(JSON.stringify(test));
    test.name = 'test'
    console.error('ddd', test, copyed)

    4、如果obj里有NaN、Infinity和-Infinity,则序列化的结果会变成null

    5、JSON.stringify()只能序列化对象的可枚举的自有属性,例如 如果obj中的对象是有构造函数生成的, 则使用JSON.parse(JSON.stringify(obj))深拷贝后,会丢弃对象的constructor;

    function Person(name) {
      this.name = name;
      console.log(name)
    }
    

    const liai = new Person(‘liai’);

    const test = {
    name: ‘a’,
    date: liai,
    };
    // debugger
    const copyed = JSON.parse(JSON.stringify(test));
    test.name = ‘test’
    console.error(‘ddd’, test, copyed)

    参考文章:关于JSON.parse(JSON.stringify(obj))实现深拷贝应该注意的坑

    9、Array.cancat(浅拷贝)

    concat将数组与值或其他数组进行组合。

    [1, 2, 3].concat(4); // [1, 2, 3, 4]
    [1, 2, 3].concat([4, 5]); // [1, 2, 3, 4, 5]

    如果我们不指定参数或者提供一个空数组作为参数,就可以进行浅拷贝。

    [1, 2, 3].concat(); // [1, 2, 3]
    [1, 2, 3].concat([]); // [1, 2, 3]

    同样的,处理对象和数组的时候是引用而不是值复制。

    10、Array.from(浅拷贝)

    可以将任何可迭代对象转换为数组。给一个数组返回一个浅拷贝。

    console.log(Array.from('foo'))
    // ['f', 'o', 'o']
    

    numbers = [1, 2, 3];
    numbersCopy = Array.from(numbers)
    // [1, 2, 3]

    同样的,处理对象和数组的时候是引用而不是值复制。


    小结

    上面这些方法都是在使用一个步骤来进行拷贝。如果我们结合一些其他的方法或技术能够发现还有很多的方式来实现数组的拷贝,比如一系列的拷贝工具函数等。


    原文地址:
    How to clone an array in JavaScript


    展开全文
  • var arr = ['old', 1, true, ['old1', 'old2'], {old: 1}] var new_arr = JSON.parse(JSON.stringify(arr)) console.log(new_arr); 复制代码

    var arr = ['old', 1, true, ['old1', 'old2'], {old: 1}]
    var new_arr = JSON.parse(JSON.stringify(arr))
    console.log(new_arr);
    复制代码


    展开全文
  • 算是整理一下,这样以便于自己以后的学习:目录浅拷贝数组拷贝数组1.使用数组遍历赋值原理代码实现2.返回新数组方法2.1 使用slice方法原理代码实现2.2 使用数组map方法2.3 使用concat方法3.ES6语法实现深拷贝4.for...

    这两天遇到了一个问题,如何复制数组,所以就从各个地方找了很多的解决办法。算是整理一下,这样以便于自己以后的学习:

    目录

    浅拷贝数组

    深拷贝数组

    1.使用数组遍历赋值

    原理

    代码实现

    2.返回新数组方法

    2.1 使用slice方法

    原理

    代码实现

    2.2 使用数组map方法

    2.3 使用concat方法

    3.ES6语法实现深拷贝

    4.for-in连原型链也一并复制的方法

    5.多维数组的复制

    浅拷贝数组

    首先第一个复制数组我们都想到的是定义一个数组直接相等就可以了:

    var arr1 = [1,2,3];

    var arr2 = arr1;

    arr1[0] = 2;

    console.log(arr1[0]); //2

    复制代码

    出现这个的原因就是因为,数组是用堆去保存的,栈中保存的是真正存储数据的内存地址,相等的时候只是拷贝了存放内存地址的栈,两个栈还是同时指向了同一个内存地址,所以在改变其中一个的值,其他的也跟着改变了,这就是所谓的浅拷贝。

    所以如何深拷贝一个数组呢?

    深拷贝数组

    1.使用数组遍历赋值

    原理

    这个是最原始的办法,就是把每个值取出来到另一个数组中。

    代码实现

    var arr1 = [1,2,3];

    var arr2 = [];

    arr1.forEach(function(value,index){

    arr2[index] = value;

    })

    console.log(arr2);

    //这个时候改变arr1[0] = 3;那么输出arr2[0]还是等于1

    复制代码

    2. 返回新数组方法

    2.1 使用slice方法

    原理

    数组的slice方法是截取数组的意思,在之前的数组总结中也有提过。

    slice(0)指的是从0开始到末尾截取数组,然后返回一个新的数组,这样就不会影响到原来的数组了。

    代码实现

    var arr1 = [1,2,3];

    var arr2 = arr1.slice(0);

    console.log(arr2); //[1,2,3]

    //这个时候改变arr1[2] = 5,那么输出arr2[2]还是等于3

    复制代码

    顺着这种方法是不是得到了思维的开阔,来看看还有哪些是返回新数组的?

    2.2使用数组map方法

    使用map方法遍历数组然后返回新的数组,里面的值不变

    var arr1 = [2,3,4];

    var arr2 = arr1.map(function(value){

    return value;

    })

    console.log(arr2); //[2,3,4]

    复制代码

    2.3使用concat方法

    连接数组,如果连接的是一个空,那么也是返回了新的本身的数组

    var arr1 = [3,4,5];

    var arr2 = arr1.concat();

    console.log(arr2); //[3,4,5]

    复制代码

    3.ES6语法实现深拷贝

    ES6扩展运算符实现数组的深拷贝,目前是最简单的。

    var arr = [1,2,3,4,5];

    var [ ... arr2 ] = arr;

    console.log(arr); //[1,2,3,4,5]

    console.log(arr2); //[1,2,3,4,5]

    复制代码

    4.for-in连原型链也一并复制的方法

    这种办法,不仅复制的值,还会把属性也进行拷贝。

    var arr = [1,2,3,4,5];

    arr.prototype = 5;

    var arr2 = [];

    for(var a in arr){

    arr2[a] = arr[a];

    }

    console.log(arr2); // [1,2,3,4,5]

    console.log(arr2.prototype); // 5

    //之前的方法中新数组的prototype都是undefined

    复制代码

    5.多维数组的复制

    原理

    多维数组转化为字符串会成为一维数组。

    var arr = [[1,2],3,4,[5,6]];

    var arr1 = arr.toString().split(",")

    var arr2 = arr.join().split(",")

    console.log(arr1) //[1,2,3,4,5,6]

    console.log(arr2) //[1,2,3,4,5,6]

    复制代码

    但是怎么可以保持那种二维数组的状态呢?需要下面的代码

    代码实现

    var arr = [[1,2],3,4,[5,6]];

    var arr3 = JSON.parse(JSON.stringify(arr));

    console.log(arr3) // [[1,2],3,4,[5,6]]

    复制代码

    如果你有新的方法欢迎留言?如果我找到新的方法会不定期更新...

    ©burning_韵七七

    展开全文
  • JavaScript中我们经常会遇到拷贝数组的场景,但是都有哪些方式能够来实现呢,我们不妨来梳理一下,感兴趣的朋友跟随小编一起看看吧
  • 数组拷贝经常被误解,但这并不是因为拷贝过程本身,而是因为缺乏对 JS 如何处理数组及其元素的理解。JS 中的数组是可变的,这说明在创建数组之后还可以修改数组的内容。 这意味着要拷贝一个数组,咱们不能简单地将...
  • 12 个拷贝数组JS 技巧 数组拷贝经常被误解,但这并不是因为拷贝过程本身,而是因为缺乏对 JS 如何处理数组及其元素的理解。JS 中的数组是可变的,这说明在创建数组之后还可以修改数组的内容。这意味着要拷贝一个...
  • JavaScript深拷贝和浅拷贝数组

    千次阅读 2017-06-09 16:23:32
    Array是引用类型,直接用“=”号赋值的话,只是把源数组的地址(或叫指针)赋值给目的数组,并没有实现数组的数据的拷贝。这种方式的实现属于浅拷贝。 对一维数组和多维数据的深拷贝实现方式是不一样的。  一、...
  • 我们在JS程序中需要进行频繁的变量赋值运算,对于字符串、布尔值等可直接使用赋值运算符 “=” 即可,但是对于数组、对象、对象数组拷贝,我们需要理解更多的内容。 首先,我们需要了解JS的浅拷贝与深拷贝的区别...
  • js中,对于字符串,布尔值可直接使用赋值运算符就可以实现深拷贝,但对于引用类型,数组,对象,对象数组拷贝呢,实际只是进行了浅拷贝   下面是一个数组 var arr = ["a","b"]; 现在...
  • 我们在JS程序中需要进行频繁的变量赋值运算,对于字符串、布尔值等可直接使用赋值运算符 “=” 即可,但是对于数组、对象、对象数组拷贝,我们需要理解更多的内容。首先,我们需要了解JS的浅拷贝与深拷贝的区别。...
  • JS里要把A数组复制到B数组 如果只是A=B赋值过去 修改B内容的时候,A内容也会随之改变   其原理是因为每个数组都会在内存里开辟一个内存区间,如果只是简单的A=B复制,只是把A的指针也复制给了B 所以A,B指针是...
  • js中如何深拷贝数组

    2020-10-12 15:36:57
    拷贝和浅拷贝的区别这里不再赘述; ... 使用后发现并不能达到效果,虽然他们都能返回一个新的数组,,,,但还是不能够彻底深拷贝,之后使用了 JSON.stringify() 和 JSON.parse() 完美解决; ...
  • javascript数组拷贝途径及对象数组拷贝 什么是浅拷贝js当中,我们常常遇到数组复制的的情况,许多人一般都会使用“=”来直接把一个数组赋值给一个变量,如: var a=[1,2,3]; var b=a; console.log(b); ...
  • 我们在JS程序中需要进行频繁的变量赋值运算,对于字符串、布尔值等可直接使用赋值运算符 “=” 即可,但是对于数组、对象、对象数组拷贝,我们需要理解更多的内容。 首先,我们需要了解JS的浅拷贝与深拷贝的...
  • javascript 数组以及对象的深拷贝(复制数组或复制对象)的方法前言在js中,数组和对象的复制如果使用=号来进行复制,那只是浅拷贝。如下图演示: 如上,arr的修改,会影响arr2的值,这显然在绝大多数情况下,并...
  • JavaScript中我们经常会遇到拷贝数组的场景,但是都有哪些方式能够来实现呢,我们不妨来梳理一下。 1、扩展运算符(浅拷贝) 自从ES6出现以来,这已经成为最流行的方法。它是一个很简单的语法,但是当你在使用类似于...
  • 拷贝简单数组时,直觉上可以这样操作。 let a=[1,2,3,4] let b=a; 但是输出打印一下进行验证。 console.log('a:',a,'b:',b) a.pop() console.log('a:',a,'b:',b) 明显不符合我们的预期。 可以用以下方法解决。 1....
  • var arr = [ { a:1 }, { a:2 }, { a:3 }, ] var copyArr = JSON.parse(JSON.stringify(arr)));
  • jq深拷贝数组

    2017-08-03 14:17:00
    通过传递第一个参数true执行了深拷贝对象中的数组(或者Object)信息. var Person = { name : 'lee', skills : ['js','css','html'] ...在工作中,经常需要深拷贝数组。网络上大部分代码都是靠for 循环来将...
  • 深浅拷贝数组

    2019-03-05 12:31:27
    3019/03/05 深拷贝,简单的使用便是用 ...但是用js代码去实现呢? 首先就是会想到遍历,去遍历数组,或者是对象。 想到遍历就会想到for 循环。 for ... of 或者 for ... in 都可以实现,区别是 for ... of 可以由 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 53,481
精华内容 21,392
关键字:

js拷贝数组