如何理解 slice() 方法是浅拷贝?深入数组浅拷贝里的小细节
2021/9/27 6:12:36
本文主要是介绍如何理解 slice() 方法是浅拷贝?深入数组浅拷贝里的小细节,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
文章目录
- slice() 方法
- 如何理解 slice() 方法的浅拷贝
- 基本对象引用赋值的浅拷贝
- 参考
slice() 方法
数组截取办法: slice()
,用于截取数组中的一部分,返回一个新的数组对象,不影响原数组。arr.slice(begin, end)
,slice
会提取原数组中索引从 begin
到 end
的所有元素(包含 begin
,但不包含 end
)。 注意 ❗ ❗ ❗ slice()
方法是浅拷贝,具体在下文做解释。
slice()
,用于截取数组中的一部分,返回一个新的数组对象,不影响原数组。
注意 ❗ ❗ ❗ slice()
方法是浅拷贝,具体在下文做解释。
arr.slice(begin, end)
,slice
会提取原数组中索引从 begin
到 end
的所有元素(包含 begin
,但不包含 end
)。
begin 可选
是提取起始处的索引(从 0 开始),从该索引开始提取原数组元素。
-
如果该参数为负数,则表示从原数组中的倒数第几个元素开始提取,slice(-2) 表示提取原数组中的倒数第二个元素到最后一个元素(包含最后一个元素)。
-
如果省略
begin
,则 slice 从索引 0 开始。 -
如果
begin
超出原数组的索引范围,则会返回空数组。
end 可选
是提取终止处的索引(从 0 开始),在该索引处结束提取原数组元素。slice 会提取原数组中索引从 begin 到 end 的所有元素(包含 begin,但不包含 end)。
-
slice(1,4)
会提取原数组中从第二个元素开始一直到第四个元素的所有元素 (索引为 1, 2, 3的元素)。 -
如果该参数为负数, 则它表示在原数组中的倒数第几个元素结束抽取。
slice(-2,-1)
表示抽取了原数组中的倒数第二个元素到最后一个元素(不包含最后一个元素,也就是只有倒数第二个元素)。 -
如果
end
被省略,则slice
会一直提取到原数组末尾。 -
如果
end
大于数组的长度,slice
也会一直提取到原数组末尾。
如何理解 slice() 方法的浅拷贝
slice 不会修改原数组,只会返回一个浅复制了原数组中的元素的一个新数组。原数组的元素会按照下述规则拷贝:
- 如果该元素是个对象引用 (不是实际的对象),
slice
会拷贝这个对象引用到新的数组里。两个对象引用都引用了同一个对象。如果被引用的对象发生改变,则新的和原来的数组中的这个元素也会发生改变。 - 对于字符串、数字及布尔值来说(不是 String、Number 或者 Boolean 对象),
slice
会拷贝这些值到新的数组里。在别的数组里修改这些字符串或数字或是布尔值,将不会影响另一个数组。
如果向两个数组任一中添加了新元素,则另一个不会受到影响。
下面通过实例详细了解一下 slice()
方法的浅拷贝:
下面的代码描述了修改数组的几种情况:
let menuTreeList = [{ "id": "cfda8029dfb311e7b555201a068c6482", "name": "系统管理", "menuType": 0, "children": [{ "id": "3873ccc2dfda11e7b555201a068c6483", "name": "菜单管理", "menuType": 2, "children": [{ "id": "18bf8d5df09511e78a57201a068c6484", "name": "新增", "menuType": 1 }, { "id": "18bf8d5df09511e78a57201a068c6485", "name": "修改", "menuType": 1 } ] }] }, { "id": "cfda8029dfb311e7b555201a068c6486", "name": "设备管理", "menuType": 0, "children": [{ "id": "18bf8d5df09511e78a57201a068c6487", "name": "新增", "menuType": 1 }, { "id": "18bf8d5df09511e78a57201a068c6488", "name": "修改", "menuType": 1 } ] } ] let a = menuTreeList.slice(0, 1); console.group("1.修改对象深层属性") // console.log('a :>> ', a); // 1.被引用的对象发生改变,则新的和原来的数组中的这个元素也会发生改变: // 修改原始值 menuTreeList[0] ,即修改对象的引用 menuTreeList[0].children = []; // 验证: // 原来的数组: console.log('被修改过的原来的数组 menuTreeList :>> ', menuTreeList); // slice方法产生的新数组: console.log('新的数组 a :>> ', a); console.groupEnd() let newArr = [1, 2, 3, 4, 5, 6]; let b = newArr.slice(0, 4); console.group("2.验证数组元素为字符串、数字及布尔值时的情况") // console.log('b :>> ', b); // 2.对于字符串、数字及布尔值来说,slice 会拷贝这些值到新的数组里。 // 在别的数组里修改这些字符串或数字或是布尔值,将不会影响另一个数组: newArr[0] = 0; newArr[1] = 0; newArr[2] = 0; newArr[3] = 0; // 原来的数组: console.log('被修改过的原来的数组 newArr :>> ', newArr); // slice方法产生的新数组: console.log('新的数组 b :>> ', b); console.groupEnd(); let newArr3 = [{ "id": "1", "name": "设备管理", "menuType": 0, }, { "id": "2", "name": "设备管理", "menuType": 0, }, { "id": "3", "name": "设备管理", "menuType": 0, }, { "id": "4", "name": "设备管理", "menuType": 0, }]; let d = newArr3.slice(0, 3); console.group("3.修改简单对象的属性 验证") // console.log('d :>> ', d); newArr3[0].id = "111111111"; newArr3[1].id = "111111111"; newArr3[2].id = "111111111"; // 原来的数组: console.log('被修改过的原来的数组 newArr3 :>> ', newArr3); // slice方法产生的新数组: console.log('新的数组 d :>> ', d); console.groupEnd(); let newArr2 = [{ "id": "1", "name": "设备管理", "menuType": 0, }, { "id": "2", "name": "设备管理", "menuType": 0, }, { "id": "3", "name": "设备管理", "menuType": 0, }, { "id": "4", "name": "设备管理", "menuType": 0, }]; let c = newArr2.slice(0, 3); console.group("4.把数组简单对象置空 验证") // console.log('c :>> ', c); newArr2[0] = {}; newArr2[1] = {}; newArr2[2] = {}; // 原来的数组: console.log('被修改过的原来的数组 newArr2 :>> ', newArr2); // slice方法产生的新数组: console.log('新的数组 c :>> ', c); console.groupEnd() let newArr4 = [{ "id": "1", "name": "设备管理", "menuType": 0, }, { "id": "2", "name": "设备管理", "menuType": 0, }, { "id": "3", "name": "设备管理", "menuType": 0, }, { "id": "4", "name": "设备管理", "menuType": 0, }]; let e = newArr4.slice(0, 3); console.group("5.把数组简单对象元素改为基本数据类型 验证") newArr4[0] = 0; newArr4[1] = 0; newArr4[2] = 0; // 原来的数组: console.log('被修改过的原来的数组 newArr4 :>> ', newArr4); // slice方法产生的新数组: console.log('新的数组 e :>> ', e); console.groupEnd()
输出结果:
为什么把数组简单对象元素改为基本数据类型
和把数组简单对象置空
这两种情况下的数组都没有跟着改变呢?
这个问题我是向 CSDN博客专家「零一」学习的,字节跳动大佬,很多高质量原创文章,快来观摩
这篇关于如何理解 slice() 方法是浅拷贝?深入数组浅拷贝里的小细节的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2025-01-12深入理解 ECMAScript 2024 新特性:Map.groupBy() 分组操作
- 2025-01-11国产医疗级心电ECG采集处理模块
- 2025-01-10Rakuten 乐天积分系统从 Cassandra 到 TiDB 的选型与实战
- 2025-01-09CMS内容管理系统是什么?如何选择适合你的平台?
- 2025-01-08CCPM如何缩短项目周期并降低风险?
- 2025-01-08Omnivore 替代品 Readeck 安装与使用教程
- 2025-01-07Cursor 收费太贵?3分钟教你接入超低价 DeepSeek-V3,代码质量逼近 Claude 3.5
- 2025-01-06PingCAP 连续两年入选 Gartner 云数据库管理系统魔力象限“荣誉提及”
- 2025-01-05Easysearch 可搜索快照功能,看这篇就够了
- 2025-01-04BOT+EPC模式在基础设施项目中的应用与优势