js中如何復(fù)制一個(gè)數(shù)組(淺復(fù)制、深復(fù)制)
在js中,我們經(jīng)常會(huì)用到數(shù)組復(fù)制,Array是引用類型,如果用arrA=arrB簡單的把一個(gè)數(shù)組賦值,并沒有創(chuàng)造出一個(gè)新數(shù)組,arrA和arrB其實(shí)指向的還是同一個(gè)地址,改變一個(gè)另一個(gè)也會(huì)隨之改變,很明顯這并不是我們想要的
? var arr = [1, 2, 3]; ? var newArr = arr; ? arr.push(4); ? console.log(newArr1); ?// [1, 2, 3, 4]
下面介紹數(shù)組的淺復(fù)制
(適用于數(shù)組并不復(fù)雜,即數(shù)組中沒有嵌套對象或者嵌套數(shù)組)
方法一:concat()
- concat()方法用于連接兩個(gè)或多個(gè)數(shù)組;
- concat() 方法不會(huì)更改現(xiàn)有數(shù)組,而是返回一個(gè)新數(shù)組,其中包含已連接數(shù)組的值。
? var arr = [1, 2, 3]; ? var newArr = arr.concat(); ? arr.push(4); ? console.log(newArr); // [1, 2, 3]
方法二:slice()
- slice() 方法以新的數(shù)組對象,返回?cái)?shù)組中被選中的元素;
- slice() 方法選擇從給定的 start 參數(shù)開始的元素,并在給定的 end 參數(shù)處結(jié)束,但不包括;
- slice() 方法不會(huì)改變原始數(shù)組;
? var arr = [1, 2, 3]; ? var newArr = arr.slice(); ? arr[0] = 10; ? console.log(arr);// [10, 2, 3] ? console.log(newArr);// [1, 2, 3]
方法三:擴(kuò)展運(yùn)算符
? var arr = [1, 2, 3]; ? var [ ...newArr ] = arr; ? arr[0] = 10; ? console.log(arr); // [10, 2, 3] ? console.log(newArr);// [1, 2, 3]
方法四: Object.assign()
?var arr = [1, 2, 3]; ?var newArr = Object.assign([], arr); ?arr[0] = 10; ?console.log(arr);// [10, 2, 3] ?console.log(newArr);// [1, 2, 3]
如果數(shù)組元素是對象或者數(shù)組,上面四種方法就會(huì)只拷貝數(shù)組或者對象的引用,如果我們對其中一個(gè)數(shù)組進(jìn)行修改,另一個(gè)數(shù)組也會(huì)發(fā)生變化
比如:
? var arr = [ { a: 1 }, [ 1, 2 ], 3 ];
? let newArr = arr.concat();
? arr[0].a = 2;
? console.log(arr); // [ { a: 2 }, [ 1, 2 ], 3 ]
? console.log(newArr);// [ { a: 2 }, [ 1, 2 ], 3 ] 值被影響下面是深復(fù)制
(可以完全拷貝一個(gè)數(shù)組,即使嵌套了對象或者數(shù)組,兩者也不會(huì)互相影響)
方法一:JSON.parse(JSON.stringify(arr))
? var arr = [ { a: 1 }, [ 1, 2 ], 3 ];
? // let newArr = JSON.parse(JSON.stringify(arr));
? let newArr = arr.concat();
? arr[0].a = 2;
? console.log(arr); // [ { a: 2 }, [ 1, 2 ], 3 ]
? console.log(newArr);// [ { a: 1 }, [ 1, 2 ], 3 ]但是該方法是有局限性的
- 會(huì)忽略 undefined
- 會(huì)忽略 symbol
- 不能序列化函數(shù)
- 不能解決循環(huán)引用的對象
比如下面這個(gè)例子:
let a = {
? age: undefined,
? sex: Symbol('male'),
? jobs: function() {},
? name: 'sun'
}
let b = JSON.parse(JSON.stringify(a))
console.log(b) // {name: "sun"}方法二:通用方法(數(shù)組或?qū)ο螅?/h3>
拷貝的時(shí)候判斷屬性值的類型,如果是對象,繼續(xù)遞歸調(diào)用深拷貝函數(shù)(簡易版)
? var deepCopy = function(obj) {
? ? // 判斷是否是對象
? ? if (typeof obj !== 'object') return;
? ? // 判斷obj類型,根據(jù)類型新建一個(gè)對象或者數(shù)組
? ? var newObj = obj instanceof Array ? [] : {}
? ? // 遍歷對象,進(jìn)行賦值
? ? for (var key in obj) {
? ? ? if (obj.hasOwnProperty(key)) {
? ? ? ? let val = obj[key];
? ? ? ? // 判斷屬性值的類型,如果是對象,遞歸調(diào)用deepCopy
? ? ? ? newObj[key] = typeof val === 'object' ? deepCopy(val) : val
? ? ? }
? ? }
? ? return newObj
? }方法三:利用lodash的深拷貝函數(shù)
_.cloneDeep(value)
其中value就是要深拷貝的值
簡單例子
var objects = [{ 'a': 1 }, { 'b': 2 }];
var deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]);
// => false在Vue中使用
安裝
npm i --save lodash
在main.js中引入
import _ from 'lodash'; Vue.prototype._ = _;
使用
let newObj = this._.cloneDeep(oldObj)
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
淺談js中調(diào)用函數(shù)時(shí)加不加括號的問題
下面小編就為大家?guī)硪黄獪\談js中調(diào)用函數(shù)時(shí)加不加括號的問題 。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-07-07
詳解Javascript中document.execCommand()的用法以及指令參數(shù)列表
execCommand方法是執(zhí)行一個(gè)對當(dāng)前文檔,當(dāng)前選擇或者給出范圍的命令。在HTML5中,execCommand可以通過JavaScript代碼來調(diào)用,使得開發(fā)者可以在網(wǎng)頁中實(shí)現(xiàn)一些復(fù)雜的文本操作。在HTML編輯器中這個(gè)命令用得很多,酷炫的強(qiáng)大功能。2023-07-07
JavaScript簡單獲取系統(tǒng)當(dāng)前時(shí)間完整示例
這篇文章主要介紹了JavaScript簡單獲取系統(tǒng)當(dāng)前時(shí)間的方法,涉及javascript針對日期與時(shí)間的判斷以及字符串組合的相關(guān)技巧,需要的朋友可以參考下2016-08-08
JavaScript模擬重力狀態(tài)下拋物運(yùn)動(dòng)的方法
這篇文章主要介紹了JavaScript模擬重力狀態(tài)下拋物運(yùn)動(dòng)的方法,實(shí)例分析了javascript操作dom元素模擬運(yùn)動(dòng)的方法,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03
js實(shí)現(xiàn)點(diǎn)擊展開隱藏效果(實(shí)例代碼)
本篇文章小編給大家?guī)硪黄P(guān)于JS實(shí)現(xiàn)點(diǎn)擊展開點(diǎn)擊隱藏的效果代碼內(nèi)容,有興趣的朋友參考下。2018-09-09
詳解JS如何使用Promise緩存網(wǎng)絡(luò)請求
網(wǎng)絡(luò)請求是現(xiàn)代Web應(yīng)用中的常見操作,很多時(shí)候需要獲取服務(wù)器上的數(shù)據(jù),在進(jìn)行網(wǎng)絡(luò)請求時(shí),為了減輕服務(wù)器的壓力,緩存策略常被用來避免對同一數(shù)據(jù)的重復(fù)請求,本文將探討如何使用Promise結(jié)合緩存來高效處理網(wǎng)絡(luò)請求,需要的朋友可以參考下2023-12-12
JS實(shí)現(xiàn)滑動(dòng)拼圖驗(yàn)證功能完整示例
這篇文章主要介紹了JS實(shí)現(xiàn)滑動(dòng)拼圖驗(yàn)證功能,結(jié)合完整實(shí)例形式分析了JS滑動(dòng)拼圖驗(yàn)證相關(guān)原理、實(shí)現(xiàn)步驟與操作注意事項(xiàng),需要的朋友可以參考下2020-03-03

