js中如何復制一個數(shù)組(淺復制、深復制)
在js中,我們經(jīng)常會用到數(shù)組復制,Array是引用類型,如果用arrA=arrB簡單的把一個數(shù)組賦值,并沒有創(chuàng)造出一個新數(shù)組,arrA和arrB其實指向的還是同一個地址,改變一個另一個也會隨之改變,很明顯這并不是我們想要的
? var arr = [1, 2, 3]; ? var newArr = arr; ? arr.push(4); ? console.log(newArr1); ?// [1, 2, 3, 4]
下面介紹數(shù)組的淺復制
(適用于數(shù)組并不復雜,即數(shù)組中沒有嵌套對象或者嵌套數(shù)組)
方法一:concat()
- concat()方法用于連接兩個或多個數(shù)組;
- concat() 方法不會更改現(xiàn)有數(shù)組,而是返回一個新數(shù)組,其中包含已連接數(shù)組的值。
? var arr = [1, 2, 3]; ? var newArr = arr.concat(); ? arr.push(4); ? console.log(newArr); // [1, 2, 3]
方法二:slice()
- slice() 方法以新的數(shù)組對象,返回數(shù)組中被選中的元素;
- slice() 方法選擇從給定的 start 參數(shù)開始的元素,并在給定的 end 參數(shù)處結(jié)束,但不包括;
- slice() 方法不會改變原始數(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]
方法三:擴展運算符
? 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ù)組,上面四種方法就會只拷貝數(shù)組或者對象的引用,如果我們對其中一個數(shù)組進行修改,另一個數(shù)組也會發(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 ] 值被影響
下面是深復制
(可以完全拷貝一個數(shù)組,即使嵌套了對象或者數(shù)組,兩者也不會互相影響)
方法一: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 ]
但是該方法是有局限性的
- 會忽略 undefined
- 會忽略 symbol
- 不能序列化函數(shù)
- 不能解決循環(huán)引用的對象
比如下面這個例子:
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>
拷貝的時候判斷屬性值的類型,如果是對象,繼續(xù)遞歸調(diào)用深拷貝函數(shù)(簡易版)
? var deepCopy = function(obj) { ? ? // 判斷是否是對象 ? ? if (typeof obj !== 'object') return; ? ? // 判斷obj類型,根據(jù)類型新建一個對象或者數(shù)組 ? ? var newObj = obj instanceof Array ? [] : {} ? ? // 遍歷對象,進行賦值 ? ? 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é)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
javascript組合使用構(gòu)造函數(shù)模式和原型模式實例
這篇文章主要介紹了javascript組合使用構(gòu)造函數(shù)模式和原型模式的方法,通過一個簡單實例分析了javascript構(gòu)造函數(shù)模式與原型模式的使用方法,需要的朋友可以參考下2015-06-06使用bootstrap-paginator.js 分頁來進行ajax 異步分頁請求示例
本篇文章主要介紹了使用bootstrap-paginator.js 分頁來進行ajax 異步分頁請求示例,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2017-03-03用js格式化金額可設(shè)置保留的小數(shù)位數(shù)
這篇文章主要介紹了如何用js格式化金額并設(shè)置保留的小數(shù)位數(shù),需要的朋友可以參考下2014-05-05?javascript數(shù)組中的slice方法和join??方法
這篇文章主要介紹了?javascript數(shù)組中的slice方法和join??方法,文章內(nèi)容介紹詳細,具有一的參考價值,需要的小伙伴可以參考一下,希望對你的學習有所幫助2022-03-03