最近的學習中,仔細研究了下深拷貝和淺拷貝,下面就來簡單的總結下。
首先我們了解下兩種 數據類型 :
1、基本類型:像Number、String、Boolean等這種為基本類型
2、復雜類型:Object和Array
接著我們分別來了解下淺拷貝和深拷貝,深拷貝和淺拷貝是只針對Object和Array這樣的復雜類型的。
淺拷貝 :
可以看出,對於對象或數組類型,當我們將a賦值給b,然後更改b中的屬性,a也會隨著變化。也就是說a和b指向了同壹塊內存,所以修改其中任意的值,另壹個值都會隨之變化,這就是淺拷貝。
深拷貝 :
剛剛我們了解了什麽是淺拷貝,那麽相應的,如果給b放到新的內存中,將a的各個屬性都復制到新內存裏,就是深拷貝。
也就是說,當b中的屬性有變化的時候,a內的屬性不會發生變化。
那麽除了上面簡單的賦值引用,還有哪些方法使用了 淺拷貝 呢?
Object.assign()
在MDN上介紹Object.assign():”Object.assign() 方法用於將所有可枚舉的屬性的值從壹個或多個源對象復制到目標對象。它將返回目標對象。”
復制壹個對象
可以看到,Object.assign()拷貝的只是屬性值,假如源對象的屬性值是壹個指向對象的引用,它也只拷貝那個引用值。所以Object.assign()只能用於淺拷貝或是合並對象。這是Object.assign()值得註意的地方。
那麽下面我們就來說說復雜的 深拷貝 。
jQuery.extend()
說到深拷貝,第壹想到的就是jQuery.extend()方法,下面我們簡單看下jQuery.extend()的使用。
jQuery.extend( [deep ], target, object1 [, objectN ] ),其中deep為Boolean類型,如果是true,則進行深拷貝。
我們還是用上面的數據來看下extend()方法。
通過上面的對比可以看出,當使用extend()進行深拷貝的時候,對象的所有屬性都添加到target中了。
我們知道了extend()可以進行深拷貝,那麽extend()是如何實現深拷貝的呢?
先來看下jQuery.extend()源碼
主要看下關於深拷貝的部分,取第壹個參數,如果是boolean類型的,就賦值給deep,下面如果deep為true(也就是進行深拷貝),就遞歸調用extend(),這樣就將對象的所有屬性都添加到了target中實現了深拷貝。
JSON.parse()和JSON.stringify()
上面的jQuery源碼是否讓妳眼花繚亂?有沒有什麽辦法無腦實現深拷貝呢?JSON.parse()和JSON.stringify()給了我們壹個基本的解決辦法。
可以看到改變targetCopy並沒有改變原始的target,繼承的屬性也沒有丟失,因此實現了基本的深拷貝。
但是用JSON.parse()和JSON.stringify()會有壹個問題。
JSON.parse()和JSON.stringify()能正確處理的對象只有Number、String、Array等能夠被json表示的數據結構,因此函數這種不能被json表示的類型將不能被正確處理。
上面的例子可以看出,hello這個屬性由於是函數類型,使用JSON.parse()和JSON.stringify()後丟失了。
因此JSON.parse()和JSON.stringify()還是需要謹慎使用。