一文詳解JavaScript中slice使用方法
slice用法
JavaScript 中的 slice() 方法用于從數(shù)組或字符串中提取一部分,并返回一個新的數(shù)組或字符串,不會修改原對象。它的用法非常靈活,支持正負索引。
1. 數(shù)組的slice()
語法
arr.slice([start[, end]])
參數(shù)
start(可選):提取起始位置的索引(從0開始)。- 如果省略,則從索引0開始。
- 如果為負數(shù),則表示從數(shù)組末尾開始計算,例如
-1表示最后一個元素,-2表示倒數(shù)第二個,以此類推。
end(可選):提取結(jié)束位置的索引(但不包含該索引對應(yīng)的元素)。- 如果省略,則一直提取到數(shù)組末尾。
- 如果為負數(shù),同樣從末尾開始計算。
- 如果
end小于等于start,則返回空數(shù)組。
返回值
一個新數(shù)組,包含提取的元素。
示例
const arr = [10, 20, 30, 40, 50]; // 從索引1開始,到索引4結(jié)束(不包括4) console.log(arr.slice(1, 4)); // [20, 30, 40] // 省略end:從索引2到末尾 console.log(arr.slice(2)); // [30, 40, 50] // 負數(shù)索引:從倒數(shù)第3個到倒數(shù)第1個(不包括倒數(shù)第1個) console.log(arr.slice(-3, -1)); // [30, 40] // 只傳一個負數(shù):從倒數(shù)第2個到末尾 console.log(arr.slice(-2)); // [40, 50] // 不傳參數(shù):復(fù)制整個數(shù)組 console.log(arr.slice()); // [10, 20, 30, 40, 50] // start大于等于數(shù)組長度:返回空數(shù)組 console.log(arr.slice(5)); // []
2. 字符串的slice()
語法
str.slice(start[, end])
參數(shù)
與數(shù)組的 slice() 完全一致:
start:起始索引(包含),負數(shù)表示從末尾倒數(shù)。end:結(jié)束索引(不包含),負數(shù)表示從末尾倒數(shù)。省略則到字符串末尾。
返回值
一個新的字符串,包含提取的子串。
示例
const str = "Hello, World!"; // 從索引7開始,到索引12結(jié)束(不包括12) console.log(str.slice(7, 12)); // "World" // 省略end:從索引7到末尾 console.log(str.slice(7)); // "World!" // 負數(shù)索引:從倒數(shù)第6個到倒數(shù)第2個(不包括倒數(shù)第2個) console.log(str.slice(-6, -1)); // "World" // 只傳一個負數(shù):從倒數(shù)第6個到末尾 console.log(str.slice(-6)); // "World!" // 復(fù)制整個字符串 console.log(str.slice()); // "Hello, World!"
3. 注意事項
- 不改變原對象:無論是數(shù)組還是字符串,
slice()都不會修改原值,而是返回一個新的副本。 - 負數(shù)索引規(guī)則:負數(shù)索引表示從末尾偏移,
-1指向最后一個元素/字符,-2指向倒數(shù)第二個,依此類推。 end參數(shù)不包含在結(jié)果中:提取的范圍是[start, end),即包含start,但不包含end。- 參數(shù)自動調(diào)整:如果
start或end超出有效范圍,會被自動限制在合法索引內(nèi)。例如start大于數(shù)組長度時,返回空數(shù)組;end大于長度時,以實際長度為準(zhǔn)。 - 適用于類數(shù)組對象:通過
call或apply,slice()也可以用于類數(shù)組對象(如arguments),將其轉(zhuǎn)換為真正的數(shù)組:
function myFunc() {
const args = Array.prototype.slice.call(arguments);
console.log(args); // 真正的數(shù)組
}
myFunc(1, 2, 3); // [1, 2, 3]
4. 與splice()的區(qū)別
slice():只讀操作,不修改原數(shù)組/字符串,返回新對象。splice():用于數(shù)組,會修改原數(shù)組,可以刪除、替換或添加元素。
5. 總結(jié)
| 用途 | 語法 | 是否修改原對象 | 返回值 |
|---|---|---|---|
| 數(shù)組提取 | arr.slice(start, end) | 否 | 新數(shù)組 |
| 字符串提取 | str.slice(start, end) | 否 | 新字符串 |
slice() 是一個簡單而強大的方法,常用于復(fù)制、截取數(shù)組或字符串的部分內(nèi)容,尤其是在需要避免副作用時非常有用。
slice()是深拷貝還是淺拷貝
slice() 方法執(zhí)行的是淺拷貝(shallow copy)。當(dāng)用于對象數(shù)組時,它只會拷貝數(shù)組中每個對象的引用,而不會遞歸地復(fù)制對象內(nèi)部的屬性。換句話說,新數(shù)組和原數(shù)組中的對應(yīng)元素指向內(nèi)存中的同一個對象。
為什么是淺拷貝?
- 基本類型元素:如果數(shù)組中包含數(shù)字、字符串、布爾值等基本類型,
slice()會直接拷貝這些值。修改新數(shù)組中的基本類型元素不會影響原數(shù)組。 - 引用類型元素:如果數(shù)組元素是對象(包括普通對象、數(shù)組、函數(shù)等),
slice()拷貝的是對象的引用。因此,新數(shù)組和原數(shù)組中的對應(yīng)元素指向同一個對象,修改該對象的屬性會同時反映在兩個數(shù)組中。
示例演示
1. 基本類型數(shù)組
const numbers = [1, 2, 3]; const newNumbers = numbers.slice(); newNumbers[0] = 100; console.log(numbers); // [1, 2, 3] (原數(shù)組不變) console.log(newNumbers); // [100, 2, 3]
2. 對象數(shù)組(淺拷貝的典型情況)
const users = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 30 }
];
const newUsers = users.slice();
// 修改新數(shù)組中對象的屬性
newUsers[0].age = 26;
console.log(users[0].age); // 26 (原數(shù)組也被修改了?。?
console.log(newUsers[0].age); // 26
3. 嵌套數(shù)組(多維數(shù)組)
const matrix = [[1, 2], [3, 4]]; const newMatrix = matrix.slice(); newMatrix[0][0] = 99; console.log(matrix[0][0]); // 99 (原數(shù)組也被修改) console.log(newMatrix[0][0]); // 99
如何實現(xiàn)深拷貝?
如果你需要對對象數(shù)組進行深拷貝(即完全復(fù)制所有層級的數(shù)據(jù),新舊數(shù)組完全獨立),可以使用以下方法:
JSON 方法(適用于可序列化的對象,不支持函數(shù)、undefined、循環(huán)引用等):
const deepCopy = JSON.parse(JSON.stringify(originalArray));
遞歸深拷貝函數(shù)(手動實現(xiàn)或使用 Lodash 的 _.cloneDeep):
// 簡單示例(未考慮循環(huán)引用等復(fù)雜情況)
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()(現(xiàn)代瀏覽器和 Node.js 17+ 支持):
const deepCopy = structuredClone(originalArray);
總結(jié)
slice()是淺拷貝,只復(fù)制一層,對于對象元素只拷貝引用。- 如果原數(shù)組包含對象,修改新數(shù)組中對象的屬性會影響原數(shù)組。
- 若需要完全獨立的副本,請使用深拷貝方法。
以上就是一文詳解JavaScript中slice使用方法的詳細內(nèi)容,更多關(guān)于JavaScript slice使用方法的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Bootstrap簡單實用的表單驗證插件BootstrapValidator用法實例詳解
這篇文章主要介紹了Bootstrap簡單實用的表單驗證插件BootstrapValidator用法,結(jié)合實例形式詳細分析了Bootstrap表單驗證插件BootstrapValidator基本功能、原理、用法及操作注意事項,需要的朋友可以參考下2020-03-03
JavaScript中string轉(zhuǎn)換成number介紹
這篇文章主要介紹了JavaScript中string轉(zhuǎn)換成number介紹,本文講解了3種將string值轉(zhuǎn)換成number的方法,需要的朋友可以參考下2014-12-12
JavaScript將當(dāng)前時間轉(zhuǎn)換成UTC標(biāo)準(zhǔn)時間的方法
這篇文章主要介紹了JavaScript將當(dāng)前時間轉(zhuǎn)換成UTC標(biāo)準(zhǔn)時間的方法,涉及javascript中Date及toUTCString方法的使用技巧,需要的朋友可以參考下2015-04-04
WebStorm ES6 語法支持設(shè)置&babel使用及自動編譯(詳解)
下面小編就為大家?guī)硪黄猈ebStorm ES6 語法支持設(shè)置&babel使用及自動編譯(詳解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-09-09
JavaScript使用Promise實現(xiàn)分批處理接口請求
當(dāng)我們在實際項目中遇到需要批量發(fā)起上百條接口請求怎么辦呢,本文就來為大家介紹一下JavaScript如何使用Promise實現(xiàn)分批處理接口請求,需要的小伙伴可以參考一下2023-11-11
微信小程序?qū)崿F(xiàn)的點擊按鈕 彈出底部上拉菜單功能示例
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)的點擊按鈕 彈出底部上拉菜單功能,結(jié)合實例形式分析了action-sheet組件及事件響應(yīng)簡單使用技巧,需要的朋友可以參考下2018-12-12

