代码之家  ›  专栏  ›  技术社区  ›  SeongUk Mun

Javascript切片方法是否返回浅拷贝?

  •  15
  • SeongUk Mun  · 技术社区  · 7 年前

    在一篇由Mozilla开发者翻译的韩文文章中,郎说“切片方法”返回了一个新的数组,该数组是粗略复制的。

    所以我测试了我的代码。

    var animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];
    
    var t = animals.slice(2,4);
    console.log(t);
    
    t[0] = 'aaa';
    console.log(t);
    console.log(animals);
    

    但是,如果切片方法返回浅数组,则应将动物数组更改为['ant'、'bison'、'aaa'、'duck'、'大象']。

    为什么是浅拷贝?

    4 回复  |  直到 6 年前
        1
  •  17
  •   Naresh Kumar    7 年前

    slice 不会改变原始数组。 它返回原始数组中元素的浅拷贝。

    原始数组的元素复制到返回的数组中,如下所示:

    对于对象引用(而不是实际对象),切片将对象引用复制到新数组中。原始数组和新数组都引用同一个对象。如果引用的对象发生更改,则新阵列和原始阵列都可以看到这些更改。

    对于字符串、数字和布尔(不是字符串、数字和布尔对象),切片将值复制到新数组中。对一个数组中的字符串、数字或布尔值的更改不会影响另一个数组。 如果将新元素添加到任意一个数组中,则另一个数组不受影响。( source )

    在您的例子中,数组由字符串组成,这些字符串在切片上会返回复制到数组的新字符串,因此是浅层副本。 为了避免这种情况,请使用数组的对象形式。

        2
  •  2
  •   klugjo    7 年前

    字符串是JavaScript中的基本类型,因此您将获得一个包含新字符串的新数组。

    测试数组应为对象数组:

    var animals = [{name: 'ant'}, {name: 'bison'}, {name: 'camel'}, {name: 'duck'}, {name: 'elephant'}];
    
    var t = animals.slice(2,4);
    console.log(t);
    
    t[0].name = 'aaa';
    console.log(t);
    console.log(animals);
        3
  •  0
  •   Orisfina    4 年前

    slice方法不会更改原始数组或字符串。它只剪切原始字符串或数组的一部分,并将其作为副本返回。 欲了解更多信息,请查看以下视频: https://youtu.be/mUH8hPQfMbg 【切片法让初学者更容易掌握】

        4
  •  0
  •   Vold    4 年前

    也许你在找这个。试试这个!

    let animals = ['ant', 'bison', 'camel', [1, 2]];
    
    let t = animals.slice();
    
    t[0] = 'aaa';    // string (primitive datatype)
    t[t.length-1][0] = 0;    // array (object)
    
    console.log(t);
    console.log(animals);
    

    如果是浅拷贝-

    • 对象将反映原始位置的更改,因为它们被存储为引用(指向堆中的地址),而不是简单地复制它们。
    • 基本数据类型将 不是 在原始位置反映更改,因为它们直接存储在调用堆栈中(在执行上下文中)。