1. 程式人生 > >ES6深拷貝與淺拷貝

ES6深拷貝與淺拷貝

olt 常用 依次 基本 對象 cnblogs 復制 過程 數據

JavaScript 中變量的賦值

結論:JavaScript中變量的賦值分為「傳值」與「傳址」。

基本數據類型的賦值,就是「傳值」;而引用類型變量賦值,實際上是「傳址」。
基本數據類型變量的賦值、比較,只是值的賦值和比較,也即棧內存中的數據的拷貝和比較,參見如下代碼:

var num1 = 123;
var num2 = 123;
var num3 = num1;
num1 === num2; // true
num1 === num3; // true
num1 = 456;
num1 === num2; // false
num1 === num3; // false

引用數據類型變量的賦值、比較,只是存於棧內存中的堆內存地址的拷貝、比較,參加如下代碼:

var arr1 = [1, 2, 3];
var arr2 = [1, 2, 3];
var arr3 = arr1;
arr1 === arr2; // false
arr1 === arr3; // true
arr1 = [1, 2, 3];
arr1 === arr2; // false
arr1 === arr3; // false

JavaScript 中變量的拷貝

JavaScript中的拷貝區分為「淺拷貝」與「深拷貝」。

淺拷貝

淺拷貝只會將對象的各個屬性進行依次復制,並不會進行遞歸復制,也就是說只會進行賦值目標對象的第一層屬性。

對於目標對象第一層為基本數據類型的數據,就是直接賦值,即「傳值」;而對於目標對象第一層為引用數據類型的數據,就是直接賦存於棧內存中的堆內存地址,即「傳址」。

深拷貝

深拷貝不同於淺拷貝,它不但拷貝目標對象的第一層屬性,而且還遞歸拷貝目標對象的所有屬性。

一般來說,在JavaScript中考慮復合類型的深層復制的時候,往往就是指對於 Date 、Object 與 Array 這三個復合類型的處理。我們能想到的最常用的方法就是先創建一個空的新對象,然後遞歸遍歷舊對象,直到發現基礎類型的子節點才賦予到新對象對應的位置。

不過這種方法會存在一個問題,就是 JavaScript 中存在著神奇的原型機制,並且這個原型會在遍歷的時候出現,然後需要考慮原型應不應該被賦予給新對象。那麽在遍歷的過程中,我們可以考慮使用 hasOwnProperty 方法來判斷是否過濾掉那些繼承自原型鏈上的屬性。

引用

1,https://juejin.im/post/5acc7e606fb9a028c67609f7
2,https://zhuanlan.zhihu.com/p/28508795
3,http://www.zsoltnagy.eu/cloning-objects-in-javascript/
4,http://www.cnblogs.com/penghuwan/p/7359026.html
5,https://blog.csdn.net/github_38524608/article/details/78812761
6,https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Spread_syntax

ES6深拷貝與淺拷貝