一文详解JavaScript中slice使用方法
slice用法
JavaScript 中的 slice() 方法用于从数组或字符串中提取一部分,并返回一个新的数组或字符串,不会修改原对象。它的用法非常灵活,支持正负索引。
1. 数组的slice()
语法
arr.slice([start[, end]])
参数
start(可选):提取起始位置的索引(从0开始)。- 如果省略,则从索引0开始。
- 如果为负数,则表示从数组末尾开始计算,例如
-1表示最后一个元素,-2表示倒数第二个,以此类推。
end(可选):提取结束位置的索引(但不包含该索引对应的元素)。- 如果省略,则一直提取到数组末尾。
- 如果为负数,同样从末尾开始计算。
- 如果
end小于等于start,则返回空数组。
返回值
一个新数组,包含提取的元素。
示例
const arr = [10, 20, 30, 40, 50]; // 从索引1开始,到索引4结束(不包括4) console.log(arr.slice(1, 4)); // [20, 30, 40] // 省略end:从索引2到末尾 console.log(arr.slice(2)); // [30, 40, 50] // 负数索引:从倒数第3个到倒数第1个(不包括倒数第1个) console.log(arr.slice(-3, -1)); // [30, 40] // 只传一个负数:从倒数第2个到末尾 console.log(arr.slice(-2)); // [40, 50] // 不传参数:复制整个数组 console.log(arr.slice()); // [10, 20, 30, 40, 50] // start大于等于数组长度:返回空数组 console.log(arr.slice(5)); // []
2. 字符串的slice()
语法
str.slice(start[, end])
参数
与数组的 slice() 完全一致:
start:起始索引(包含),负数表示从末尾倒数。end:结束索引(不包含),负数表示从末尾倒数。省略则到字符串末尾。
返回值
一个新的字符串,包含提取的子串。
示例
const str = "Hello, World!"; // 从索引7开始,到索引12结束(不包括12) console.log(str.slice(7, 12)); // "World" // 省略end:从索引7到末尾 console.log(str.slice(7)); // "World!" // 负数索引:从倒数第6个到倒数第2个(不包括倒数第2个) console.log(str.slice(-6, -1)); // "World" // 只传一个负数:从倒数第6个到末尾 console.log(str.slice(-6)); // "World!" // 复制整个字符串 console.log(str.slice()); // "Hello, World!"
3. 注意事项
- 不改变原对象:无论是数组还是字符串,
slice()都不会修改原值,而是返回一个新的副本。 - 负数索引规则:负数索引表示从末尾偏移,
-1指向最后一个元素/字符,-2指向倒数第二个,依此类推。 end参数不包含在结果中:提取的范围是[start, end),即包含start,但不包含end。- 参数自动调整:如果
start或end超出有效范围,会被自动限制在合法索引内。例如start大于数组长度时,返回空数组;end大于长度时,以实际长度为准。 - 适用于类数组对象:通过
call或apply,slice()也可以用于类数组对象(如arguments),将其转换为真正的数组:
function myFunc() {
const args = Array.prototype.slice.call(arguments);
console.log(args); // 真正的数组
}
myFunc(1, 2, 3); // [1, 2, 3]
4. 与splice()的区别
slice():只读操作,不修改原数组/字符串,返回新对象。splice():用于数组,会修改原数组,可以删除、替换或添加元素。
5. 总结
| 用途 | 语法 | 是否修改原对象 | 返回值 |
|---|---|---|---|
| 数组提取 | arr.slice(start, end) | 否 | 新数组 |
| 字符串提取 | str.slice(start, end) | 否 | 新字符串 |
slice() 是一个简单而强大的方法,常用于复制、截取数组或字符串的部分内容,尤其是在需要避免副作用时非常有用。
slice()是深拷贝还是浅拷贝
slice() 方法执行的是浅拷贝(shallow copy)。当用于对象数组时,它只会拷贝数组中每个对象的引用,而不会递归地复制对象内部的属性。换句话说,新数组和原数组中的对应元素指向内存中的同一个对象。
为什么是浅拷贝?
- 基本类型元素:如果数组中包含数字、字符串、布尔值等基本类型,
slice()会直接拷贝这些值。修改新数组中的基本类型元素不会影响原数组。 - 引用类型元素:如果数组元素是对象(包括普通对象、数组、函数等),
slice()拷贝的是对象的引用。因此,新数组和原数组中的对应元素指向同一个对象,修改该对象的属性会同时反映在两个数组中。
示例演示
1. 基本类型数组
const numbers = [1, 2, 3]; const newNumbers = numbers.slice(); newNumbers[0] = 100; console.log(numbers); // [1, 2, 3] (原数组不变) console.log(newNumbers); // [100, 2, 3]
2. 对象数组(浅拷贝的典型情况)
const users = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 30 }
];
const newUsers = users.slice();
// 修改新数组中对象的属性
newUsers[0].age = 26;
console.log(users[0].age); // 26 (原数组也被修改了!)
console.log(newUsers[0].age); // 26
3. 嵌套数组(多维数组)
const matrix = [[1, 2], [3, 4]]; const newMatrix = matrix.slice(); newMatrix[0][0] = 99; console.log(matrix[0][0]); // 99 (原数组也被修改) console.log(newMatrix[0][0]); // 99
如何实现深拷贝?
如果你需要对对象数组进行深拷贝(即完全复制所有层级的数据,新旧数组完全独立),可以使用以下方法:
JSON 方法(适用于可序列化的对象,不支持函数、undefined、循环引用等):
const deepCopy = JSON.parse(JSON.stringify(originalArray));
递归深拷贝函数(手动实现或使用 Lodash 的 _.cloneDeep):
// 简单示例(未考虑循环引用等复杂情况)
function deepClone(obj) {
if (obj === null || typeof obj !== 'object') return obj;
if (Array.isArray(obj)) return obj.map(item => deepClone(item));
const clonedObj = {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
clonedObj[key] = deepClone(obj[key]);
}
}
return clonedObj;
}
使用 structuredClone()(现代浏览器和 Node.js 17+ 支持):
const deepCopy = structuredClone(originalArray);
总结
slice()是浅拷贝,只复制一层,对于对象元素只拷贝引用。- 如果原数组包含对象,修改新数组中对象的属性会影响原数组。
- 若需要完全独立的副本,请使用深拷贝方法。
以上就是一文详解JavaScript中slice使用方法的详细内容,更多关于JavaScript slice使用方法的资料请关注脚本之家其它相关文章!
相关文章
JavaScript给input的value赋值引发的关于基本类型值和引用类型值问题
这篇文章主要介绍了JavaScript给input的value赋值引发的关于基本类型值和引用类型值问题的相关资料,需要的朋友可以参考下2015-12-12
使用weixin-java-tools完成微信授权登录、微信支付的示例
这篇文章主要介绍了使用weixin-java-tools完成微信授权登录、微信支付的示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧2018-09-09


最新评论