Javascript的slice方法是否返回浅拷贝?

19
在Mozilla开发者翻译的韩文中,'slice方法'返回一个浅复制的新数组。因此,我测试了我的代码。
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','elephant']。

为什么是浅拷贝?


1
你刚才不是引用了文档说明它是浅拷贝并且不会改变原始数据吗?我不明白你的问题。 - Bergi
@Bergi 我认为文档读起来像是一个矛盾。浅拷贝与旧拷贝具有相同的内存地址。因此,对它们中的任何一个进行更改都会更改两者的属性。但在上面的示例中,这种情况并没有发生。 - sunwarr10r
@sunwarri0r “浅复制与旧的对象具有相同的内存地址”- 不,它不是这样的。你在哪里读到的? - Bergi
1
我认为这是作者的理解,这就是他提出这个问题的原因。同时我的评论是错误的,希望这篇文章也能帮助其他人 https://en.m.wikipedia.org/wiki/Object_copying#Shallow_copy - sunwarr10r
5个回答

20

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

源数组的元素被复制到返回的新数组中:

对于对象引用(而不是实际对象),slice 将对象引用复制到新数组中。原始数组和新数组都指向同一个对象。如果引用的对象发生更改,则这些更改对新数组和原始数组均可见。

对于字符串、数字和布尔值(而不是 String、Number 和 Boolean 对象),slice 复制这些值到新数组中。在一个数组中更改字符串、数字或布尔值不会影响另一个数组。如果将新元素添加到任何一个数组,则不会影响另一个数组。(来源

在您的情况下,数组由字符串组成,在对其进行 slice 操作后将返回已复制到该数组的新字符串,因此是浅拷贝。为了避免这种情况,请使用数组的对象形式。


2

字符串是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);


1
我认为这篇文章可能会有所帮助: 例如,如果在一个名为copy的浅拷贝数组对象中,copy[0]元素的值是{"list":["butter","flour"]},然后你执行copy[0].list = ["oil","flour"],那么源对象中对应的元素也会改变,因为你选择性地改变了源对象和浅拷贝共享的对象的属性。
然而,如果你执行copy[0] = {"list":["oil","flour"]},那么源对象中对应的元素不会改变,因为在这种情况下,你不仅仅是选择性地改变了浅拷贝与源对象共享的现有数组元素的属性;相反,你实际上是在浅拷贝中给copy[0]数组元素赋予了一个全新的值。

0

slice方法不会改变原始数组或字符串。它只是从原始字符串或数组中剪切一部分并将其作为副本返回。 为了更好地理解它,请查看下面的视频: https://youtu.be/mUH8hPQfMbg [针对绝对初学者的简化版slice方法]


0

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

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

在进行浅拷贝的情况下-
  • 对象将反映原始位置中的更改,因为它们被存储为引用(指向堆中的地址)。
  • 原始数据类型不会反映原始位置中的更改,因为它们直接存储在调用堆栈(执行上下文)中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接