由于數(shù)組不是js的基本類型,我們在對數(shù)組進行備份,如果只是簡單的將它賦值給其他變量,那么我們只要改變其中任何一個,其他的變量的數(shù)組也會跟著改變。實際應(yīng)用中就會產(chǎn)生bug
// 淺復(fù)制
var arr = ["one","two","three"];
var arrto = arr;
console.log(arr, arrto); // ["one","two","three"] ["one","two","three"]
arrto[0] = 1;
console.log(arr, arrto); // [1,"two","three"] ["one","two","three"]
改變數(shù)組arrto,arr也會受到影響,像這種直接賦值數(shù)組的方式就是淺復(fù)制,引發(fā)這種現(xiàn)象的原因是因為數(shù)組是引用數(shù)據(jù)類型,arrto = arr 是將arr數(shù)組的引用地址傳遞給了 arrto,arrto 與 arr 指向的是同一個數(shù)組。要避免這類情況發(fā)生我們可以 對數(shù)組進行深復(fù)制
// 深復(fù)制
var arr = ["one","two","three"];
var arrto = [];
for (var i = 0; i < arr.length; i++) {
arrto[i] = arr[i];
}
console.log(arr, arrto); // ["one","two","three"] ["one","two","three"]
arrto[0] = 1;
console.log(arr, arrto); // ["one","two","three"] [1,"two","three"]
arr數(shù)組中的每個元素都是字符串,屬于js的基本類型,可以直接傳遞值,遍歷數(shù)組arr將數(shù)組中的每個元素傳給新數(shù)組arrto就能實現(xiàn)數(shù)組的深復(fù)制。
使用一些js的函數(shù)也能實現(xiàn)數(shù)組的深復(fù)制
使用js內(nèi)置函數(shù)實現(xiàn)深復(fù)制
1.slice 可以從已有的數(shù)組中返回選定的元素,且返回的是一個新數(shù)組
var arr = ["one","two","three"];
var arrto = arr.slice(0);
console.log(arr, arrto); // ["one","two","three"] ["one","two","three"]
arrto[0] = 1;
console.log(arr, arrto); // ["one","two","three"] [1,"two","three"]
使用slice返回新數(shù)組后改變arrto的值,arr并未改變
2.concat : 連接兩個或多個數(shù)組,返回新數(shù)組
var arr = ["one","two","three"];
var arrto = arr.concat([]);
console.log(arr, arrto); // ["one","two","three"] ["one","two","three"]
arrto[0] = 1;
console.log(arr, arrto); // ["one","two","three"] [1,"two","three"]
3.map :返回一個由原數(shù)組中的每個元素調(diào)用一個指定方法后的返回值組成的新數(shù)組。
var arr = ["one","two","three"];
var arrto = arr.map(ele=>ele);
console.log(arr, arrto); // ["one","two","three"] ["one","two","three"]
arrto[0] = 1;
console.log(arr, arrto); // ["one","two","three"] [1,"two","three"]
總結(jié):數(shù)組由于不是js的基本類型,不能進行直接傳值,需要遍歷數(shù)組的每一個基本類型的元素傳值,最后構(gòu)建新的數(shù)組。與數(shù)組類似 ,js的對象也直接復(fù)制也會產(chǎn)生與數(shù)組相同的問題,要實現(xiàn)深拷貝,需遍歷對象的每個屬性。