JS的拷貝可分為淺拷貝和深拷貝:
淺拷貝:如果數組元素是基本類型,就會拷貝一份,互不影響,而如果是對象或者數組,就會只拷貝對象和數組的引用,這樣我們無論在新舊數組進行了修改,兩者都會發生變化。
深拷貝:就是指完全的拷貝一個對象,即使嵌套了對象,兩者也相互分離,修改一個對象的屬性,也不會影響另一個。
通常我們用的slice(截取)、concat(拼接)函數,都是淺拷貝。
// 可用concat、slice返回一個新數組的特性來實現拷貝 var arr = ['old', 1, true, null, undefined]; var new_arr = arr.concat(); // 或者var new_arr = arr.slice()也是一樣的效果; new_arr[0] = 'new'; console.log(arr); // ["old", 1, true, null, undefined] console.log(new_arr); // ["new", 1, true, null, undefined] // 數組嵌套了對象或者數組的話用concat、slice拷貝只要有修改會引起新舊數組都一起改變 var arr = [{old: 'old'}, ['old']]; var new_arr = arr.concat(); // 或者var new_arr = arr.slice()也是一樣的效果; arr[0].old = 'new'; new_arr[1][0] = 'new'; console.log(arr); // [{old: 'new'}, ['new']] console.log(new_arr); // [{old: 'new'}, ['new']]
如果需要深拷貝,有如下2種方法:
1:可拷貝數組和對象(但不能拷貝函數)
var arr = ['old', 1, true, ['old1', 'old2'], {old: 1}] var new_arr = JSON.parse(JSON.stringify(arr)) console.log(new_arr);
2.函數實現,拷貝的時候判斷屬性值的類型,如果是對象,繼續遞歸調用深拷貝函數
function(obj) { // 只拷貝對象 if (typeof obj !== 'object') return; // 根據obj的類型判斷是新建一個數組還是一個對象 var newObj = obj instanceof Array ? [] : {}; for (var key in obj) { // 遍歷obj,並且判斷是obj的屬性才拷貝 if (obj.hasOwnProperty(key)) { // 判斷屬性值的類型,如果是對象遞歸調用深拷貝 newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key]; //改成下面的代碼,就是淺拷貝 //newObj[key] = obj[key]; } } return newObj; }
參考文章:https://blog.csdn.net/qq_37268201/article/details/80448848