一文详解JavaScript中slice使用方法

 更新时间:2026年02月25日 09:39:46   作者:Never_Satisfied  
文章介绍了JavaScript中的slice()方法,该方法用于提取数组或字符串的子部分,返回新数组或字符串,不改变原对象,支持正负索引,适用于数组和字符串,且有注意事项,最后,文章解释了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
  • 参数自动调整:如果 startend 超出有效范围,会被自动限制在合法索引内。例如 start 大于数组长度时,返回空数组;end 大于长度时,以实际长度为准。
  • 适用于类数组对象:通过 callapplyslice() 也可以用于类数组对象(如 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使用方法的资料请关注脚本之家其它相关文章!

相关文章

最新评论