1. 程式人生 > >js實現陣列淺拷貝和深拷貝

js實現陣列淺拷貝和深拷貝

// 陣列的淺拷貝,可用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();
arr[0].old = 'new';
new_arr[1][0] = 'new';
console.log(arr); // [{old: 'new'}, ['new']]
console.log(new_arr); // [{old: 'new'}, ['new']]

// 如果陣列元素是基本型別,就會拷貝一份,互不影響,而如果是物件或者陣列,就會只拷貝物件和陣列的引用,這樣我們無論在新舊陣列進行了修改,兩者都會發生變化。這種叫淺拷貝
// 深拷貝就是指完全的拷貝一個物件,即使嵌套了物件,兩者也相互分離,修改一個物件的屬性,也不會影響另一個。

// 陣列的深拷貝
// 技巧一:不僅可拷貝陣列還能拷貝物件(但不能拷貝函式)

var arr = ['old', 1, true, ['old1', 'old2'], {old: 1}]
var new_arr = JSON.parse(JSON.stringify(arr))
console.log(new_arr);

// 下面是淺拷貝一個通用方法,實現思路:遍歷物件,把屬性和屬性值都放在一個新的物件裡

var shallowCopy = function (obj) {
  // 只拷貝物件
  if (typeof obj !== 'object') return;
  // 根據obj的型別判斷是新建一個數組還是一個物件
var newObj = obj instanceof Array ? [] : {}; // 遍歷obj,並且判斷是obj的屬性才拷貝 for (var key in obj) { if (obj.hasOwnProperty(key)) { newObj[key] = obj[key]; } } return newObj; }

// 下面是深拷貝一個通用方法,實現思路:拷貝的時候判斷屬性值的型別,如果是物件,繼續遞迴呼叫深拷貝函式

var deepCopy = 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];
    }
  }
  return newObj;
}