【js】const與let在聲明對象或數組時的區別

這是我當時向一位網友提出的問題,這位網友就拿const作用域及能否改值來回答,似乎沒有明白我的問題關鍵所在。

做個試驗:

const obj1 = {
	a: 36,
	b: [36]
};
const obj2 = obj1;
obj2["a"] = 24;
obj2["b"][0] = 48;
console.log(obj1.a); // 24
console.log(obj2.a); // 24
console.log(obj1.b); // Array [ 48 ]
console.log(obj2.b); // Array [ 48 ]

我們發現const對於Object基本沒有用,當然Array也是一樣。也就是說,上面的const換成let也是一樣的。

如果我們將賦值方式改為Object.assign又會發生甚麼呢?

const obj1 = {
	a: 36,
	b: [36]
};
const obj2 = Object.assign({}, obj1);
obj2["a"] = 24;
obj2["b"][0] = 48;
console.log(obj1.a); // 36
console.log(obj2.a); // 24
console.log(obj1.b); // Array [ 48 ]
console.log(obj2.b); // Array [ 48 ]

說明這時obj2.a的指針已經不同於obj1.a

對於Function, Class, Object, Array這些類型而言,值存的是指針地址。賦值也是指針地址。而assign給了obj2.a一個新的指針地址指向新的值;obj2.b仍然指向了同一個地址,因為它的數據類型是Array。

如果我們希望obj2.b也是一個新的指針呢?有兩種辦法。

一種是先delete obj2.b,再重新賦值。

第二種是deepcopy。

deepcopy最簡單的方式是json:

let b = JSON.parse(JSON.stringify(a));

但json對於空值如undifined、none、null,會統一轉為null。

因此考慮用下面的函數:

function deepCopy(obj) {
  let _obj = {};
  for(let key in obj) {
    _obj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key];
  }
  return _obj;
}

這個方法會使Array轉為Object類型,問題不大。

Leave a Comment