摘要:實(shí)現(xiàn)實(shí)現(xiàn)一個(gè)深拷貝函數(shù),就不得不說的數(shù)值類型。類型來看下面代碼,結(jié)果會(huì)返回啥呢答案是有時(shí)候保存了元素,一不小心進(jìn)行深拷貝,上面的深拷貝函數(shù)就缺少了對(duì)元素的判斷。在不同的場(chǎng)景下,要根據(jù)業(yè)務(wù)場(chǎng)景,判斷是否需要使用深拷貝。
javascript深拷貝是初學(xué)者甚至有經(jīng)驗(yàn)的開發(fā)著,都會(huì)經(jīng)常遇到問題,并不能很好的理解javascript的深拷貝。
深拷貝(deepClone)?與深拷貝相對(duì)的就是淺拷貝,很多初學(xué)者在接觸這個(gè)感念的時(shí)候,是很懵逼的。
在很多情況下,我們都需要給變量賦值,給內(nèi)存地址賦予一個(gè)值,但是在賦值引用值類型的時(shí)候,只是共享一個(gè)內(nèi)存區(qū)域,導(dǎo)致賦值的時(shí)候,還跟之前的值保持一直性。
看一個(gè)具體的例子
// 給test賦值了一個(gè)對(duì)象 var test = { a: "a", b: "b" }; // 將test賦值給test2 // 此時(shí)test和test2是共享了同一塊內(nèi)存對(duì)象,這也就是淺拷貝 var test2 = test; test2.a = "a2"; test.a === "a2"http:// 為true
圖解:
這下就很好理解為什么引用值類型數(shù)據(jù)相互影響問題。
實(shí)現(xiàn)實(shí)現(xiàn)一個(gè)深拷貝函數(shù),就不得不說javascript的數(shù)值類型。
判斷javascript類型javascript中有以下基本類型
類型 | 描述 |
---|---|
undefined | undefined類型只有一個(gè)值undefined,它是變量未被賦值時(shí)的值 |
null | null類型也只有一個(gè)值null, 它是一個(gè)空的對(duì)象引用 |
Boolean | Boolean有兩種取值true和false |
String | 它表示文本信息 |
Number | 它表示數(shù)字信息 |
Object | 它是一系列屬性的無序集合, 包括函數(shù)Function和數(shù)組Array |
使用typeof是無法判斷function和array的,這里使用Object.prototype.toString方法。
[默認(rèn)情況下,每個(gè)對(duì)象都會(huì)從Object上繼承到toString()方法,如果這個(gè)方法沒有被這個(gè)對(duì)象自身或者更接近的上層原型上的同名方法覆蓋(遮蔽),則調(diào)用該對(duì)象的toString()方法時(shí)會(huì)返回"[object type]",這里的字符串type表示了一個(gè)對(duì)象類型][1]
function type(obj) { var toString = Object.prototype.toString; var map = { "[object Boolean]" : "boolean", "[object Number]" : "number", "[object String]" : "string", "[object Function]" : "function", "[object Array]" : "array", "[object Date]" : "date", "[object RegExp]" : "regExp", "[object Undefined]": "undefined", "[object Null]" : "null", "[object Object]" : "object" }; return map[toString.call(obj)]; }實(shí)現(xiàn)deepClone
對(duì)于非引用值類型的數(shù)值,直接賦值,而對(duì)于引用值類型(object)還需要再次遍歷,遞歸賦值。
function deepClone(data) { var t = type(data), o, i, ni; if(t === "array") { o = []; }else if( t === "object") { o = {}; }else { return data; } if(t === "array") { for (i = 0, ni = data.length; i < ni; i++) { o.push(deepClone(data[i])); } return o; }else if( t === "object") { for( i in data) { o[i] = deepClone(data[i]); } return o; } }
這里有個(gè)點(diǎn)大家要注意下,對(duì)于function類型,博主這里是直接賦值的,還是共享一個(gè)內(nèi)存值。這是因?yàn)楹瘮?shù)更多的是完成某些功能,有個(gè)輸入值和返回值,而且對(duì)于上層業(yè)務(wù)而言更多的是完成業(yè)務(wù)功能,并不需要真正將函數(shù)深拷貝。
但是function類型要怎么拷貝呢?
其實(shí)博主只想到了用new來操作一下,但是function就會(huì)執(zhí)行一遍,不敢想象會(huì)有什么執(zhí)行結(jié)果哦!o(╯□╰)o!其它暫時(shí)還沒有什么好的想法,歡迎大家指導(dǎo)哦!
到這里差不多也就實(shí)現(xiàn)完了深拷貝,又有人覺的怎么沒有實(shí)現(xiàn)淺拷貝呢?
淺拷貝?對(duì)于淺拷貝而言,可以理解為只操作一個(gè)共同的內(nèi)存區(qū)域!這里會(huì)存在危險(xiǎn)!(。﹏。*)
如果直接操作這個(gè)共享的數(shù)據(jù),不做控制的話,會(huì)經(jīng)常出現(xiàn)數(shù)據(jù)異常,被其它部分更改。所以應(yīng)該不要直接操作數(shù)據(jù)源,給數(shù)據(jù)源封裝一些方法,來對(duì)數(shù)據(jù)來進(jìn)行CURD操作。
到這里估計(jì)就差不多了,但是作為一個(gè)前端,不僅僅考慮javascript本身,還得考慮到dom、瀏覽器等。
Element類型來看下面代碼,結(jié)果會(huì)返回啥呢?
Object.prototype.toString.call(document.getElementsByTagName("div")[0])
答案是[object HTMLDivElement]
有時(shí)候保存了dom元素, 一不小心進(jìn)行深拷貝,上面的深拷貝函數(shù)就缺少了對(duì)Element元素的判斷。而判斷Element元素要使用instanceof來判斷。因?yàn)閷?duì)于不同的標(biāo)簽,tostring會(huì)返回對(duì)應(yīng)不同的標(biāo)簽的構(gòu)造函數(shù)。
function type(obj) { var toString = Object.prototype.toString; var map = { "[object Boolean]" : "boolean", "[object Number]" : "number", "[object String]" : "string", "[object Function]" : "function", "[object Array]" : "array", "[object Date]" : "date", "[object RegExp]" : "regExp", "[object Undefined]": "undefined", "[object Null]" : "null", "[object Object]" : "object" }; if(obj instanceof Element) { return "element"; } return map[toString.call(obj)]; }其它方式?
jquery的實(shí)現(xiàn)
詳見https://github.com/jquery/jqu...
underscore的實(shí)現(xiàn)
詳見https://github.com/jashkenas/...
lodash的實(shí)現(xiàn)
詳見https://github.com/lodash/lod...
JSON實(shí)現(xiàn)
先通過JSON.stringify一下,然后再JSON.parse一下,就能實(shí)現(xiàn)深拷貝。但是數(shù)據(jù)類型只支持基本數(shù)值類型。
var obj = { a: "a", b: function(){console.log("b")} } //在JSON.stringify的時(shí)候就會(huì)把function給過濾了。 JSON.stringify(obj)// "{"a":"a"}"小結(jié)
這里大概總結(jié)了一下深拷貝,以及怎么實(shí)現(xiàn)一個(gè)深拷貝。在不同的場(chǎng)景下,要根據(jù)業(yè)務(wù)場(chǎng)景,判斷是否需要使用深拷貝。
原文鏈接 http://xiaoqiang730730.github...
winter-JavaScript中的類型
http://www.cnblogs.com/winter...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/80149.html
摘要:要理解中淺拷貝和深拷貝的區(qū)別,首先要明白的數(shù)據(jù)類型有兩種數(shù)據(jù)類型,基礎(chǔ)數(shù)據(jù)類型和引用數(shù)據(jù)類型基礎(chǔ)數(shù)據(jù)類型保存在棧內(nèi)存中的簡(jiǎn)單數(shù)據(jù)段,有,,,,引用數(shù)據(jù)類型,對(duì)象,保存在堆內(nèi)存空間中存放在棧內(nèi)存中與變量名與內(nèi)存地址存儲(chǔ)在棧內(nèi)存中,與作為對(duì)象存 要理解 JavaScript中淺拷貝和深拷貝的區(qū)別,首先要明白JavaScript的數(shù)據(jù)類型 JavaScript有兩種數(shù)據(jù)類型,基礎(chǔ)數(shù)據(jù)類型和引...
摘要:在中可以通過添加一個(gè)參數(shù)來實(shí)現(xiàn)遞歸,調(diào)用就可以實(shí)現(xiàn)一個(gè)深拷貝。利用序列化實(shí)現(xiàn)一個(gè)深拷貝 在JavaScript中,對(duì)于Object和Array這類引用類型值,當(dāng)從一個(gè)變量向另一個(gè)變量復(fù)制引用類型值時(shí),這個(gè)值的副本其實(shí)是一個(gè)指針,兩個(gè)變量指向同一個(gè)堆對(duì)象,改變其中一個(gè)變量,另一個(gè)也會(huì)受到影響。 這種拷貝分為兩種情況:拷貝引用和拷貝實(shí)例,也就是我們說的淺拷貝和深拷貝 淺拷貝(shallow...
摘要:相信人很多學(xué)習(xí)的過程中都踩了深拷貝和淺拷貝的坑,深拷貝和淺拷貝的區(qū)別我就不再贅述了,今天我來寫一下我自己實(shí)現(xiàn)深拷貝的各種方法。中的深拷貝也是用類似方法實(shí)現(xiàn)。 相信人很多學(xué)習(xí)js的過程中都踩了深拷貝和淺拷貝的坑,深拷貝和淺拷貝的區(qū)別我就不再贅述了,今天我來寫一下我自己實(shí)現(xiàn)深拷貝的各種方法。 比較簡(jiǎn)單的拷貝方式可以借用瀏覽器的Json對(duì)象去實(shí)現(xiàn),先把對(duì)象轉(zhuǎn)化為json字符串,在解析回對(duì)...
摘要:基本數(shù)據(jù)類型的復(fù)制很簡(jiǎn)單,就是賦值操作,所以深淺拷貝也是針對(duì),這類引用類型數(shù)據(jù)。它會(huì)拋棄對(duì)象的。另外,查資料過程中還看到這么一個(gè)詞結(jié)構(gòu)化克隆算法還有這一篇資料也有參考,也寫得比較詳細(xì)了的深淺拷貝 基本數(shù)據(jù)類型的復(fù)制很簡(jiǎn)單,就是賦值操作,所以深淺拷貝也是針對(duì)Object,Array這類引用類型數(shù)據(jù)。 淺拷貝對(duì)于字符串來說,是值的復(fù)制,而對(duì)于對(duì)象來說則是對(duì)對(duì)象地址的復(fù)制;而深拷貝的話,它不...
摘要:深復(fù)制實(shí)現(xiàn)代碼如下第一種方法通過遞歸解析解決第二種方法通過解析解決作者六師兄鏈接原生深拷貝的實(shí)現(xiàn)處理未輸入新對(duì)象的情況通過方法構(gòu)造新的對(duì)象 深淺拷貝針對(duì)的是 對(duì)象類型,如果是字符串的數(shù)組用[...arr],還是不會(huì)影響 要區(qū)分針對(duì)數(shù)組的深淺拷貝(默認(rèn)情況為里面沒有對(duì)象的數(shù)組),與針對(duì)對(duì)象的深淺拷貝 JavaScript數(shù)組深拷貝和淺拷貝的兩種方法 let a1 = [1, 2]; ...
閱讀 3715·2021-11-19 09:40
閱讀 3166·2019-08-30 15:54
閱讀 2370·2019-08-30 15:44
閱讀 3257·2019-08-29 15:35
閱讀 3390·2019-08-29 12:22
閱讀 2917·2019-08-28 18:01
閱讀 3208·2019-08-26 13:54
閱讀 970·2019-08-26 12:24