数组截取办法: 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
会拷贝这些值到新的数组里。在别的数组里修改这些字符串或数字或是布尔值,将不会影响另一个数组。如果向两个数组任一中添加了新元素,则另一个不会受到影响。
下面通过实例详细了解一下 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博客专家「零一」学习的,字节跳动大佬,很多高质量原创文章,快来观摩