在JavaScript中,數據的復制可以分為淺拷貝(Shallow Copy)和深拷貝(Deep Copy)。這兩種拷貝方式主要區別在于如何處理對象中的嵌套對象。下面我會詳細解釋這兩者的概念、區別,并提供相應的實現代碼。
淺拷貝
淺拷貝是指創建一個新的對象,這個新對象的屬性值是原對象屬性值的引用(對于原始類型如字符串、數字、布爾值等是值的拷貝,而對于對象、數組等復雜類型則是引用的拷貝)。如果原對象的某個屬性是一個對象,那么淺拷貝得到的新對象對應的屬性將指向原對象中該屬性所指向的對象的內存地址,也就是說拷貝得到的是同一個對象的引用。
實現淺拷貝的方法:
-
Object.assign()
const obj = { a: 1, b: { c: 2 } }; const shallowCopy = Object.assign({}, obj);
-
Spread Operator (擴展運算符)
const obj = { a: 1, b: { c: 2 } }; const shallowCopy = { ...obj };
深拷貝
深拷貝則是遞歸地拷貝原對象的所有層級,直到遇到不可遍歷的值(如基本類型)。這意味著,無論對象的嵌套層次多深,深拷貝都會創建一個全新的對象,擁有與原對象相同內容但完全不同內存地址的副本,包括所有子對象也會被拷貝。
實現深拷貝的方法:
-
JSON.parse() 和 JSON.stringify()
注意這種方法對于函數、undefined、循環引用等情況不適用。const obj = { a: 1, b: { c: 2 } }; const deepCopy = JSON.parse(JSON.stringify(obj));
-
遞歸實現
這種方法可以處理更多復雜情況,如函數、日期對象等。function deepClone(obj, hash = new WeakMap()) {if (obj === null || typeof obj !== 'object') return obj;if (hash.has(obj)) return hash.get(obj);let cloneObj = new obj.constructor();hash.set(obj, cloneObj);for (let key in obj) {if (obj.hasOwnProperty(key)) {cloneObj[key] = deepClone(obj[key], hash);}}return cloneObj; }const obj = { a: 1, b: { c: 2 }, d: new Date() }; const deepCopy = deepClone(obj);
總結
- 淺拷貝只拷貝一層,對于對象或數組中的嵌套對象只是拷貝了引用。
- 深拷貝會遞歸拷貝所有層級,創建一個完全獨立的副本。