自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Javascript深拷貝

開發(fā) 前端
javascript深拷貝是初學(xué)者甚至有經(jīng)驗(yàn)的開發(fā)者,都會(huì)經(jīng)常遇到問題,并不能很好的理解javascript的深拷貝。

[[192119]]

javascript深拷貝是初學(xué)者甚至有經(jīng)驗(yàn)的開發(fā)者,都會(huì)經(jīng)常遇到問題,并不能很好的理解javascript的深拷貝。

深拷貝(deepClone)?

與深拷貝相對(duì)的就是淺拷貝,很多初學(xué)者在接觸這個(gè)感念的時(shí)候,是很懵逼的。 

[[192120]] 

為啥要用深拷貝?

在很多情況下,我們都需要給變量賦值,給內(nèi)存地址賦予一個(gè)值,但是在賦值引用值類型的時(shí)候,只是共享一個(gè)內(nèi)存區(qū)域,導(dǎo)致賦值的時(shí)候,還跟之前的值保持一直性。

看一個(gè)具體的例子

  1. // 給test賦值了一個(gè)對(duì)象 
  2.  
  3. var test = { 
  4.  
  5. a: 'a'
  6.  
  7. b: 'b' 
  8.  
  9. }; 
  10.  
  11.   
  12.  
  13. // 將test賦值給test2 
  14.  
  15. // 此時(shí)test和test2是共享了同一塊內(nèi)存對(duì)象,這也就是淺拷貝 
  16.  
  17. var test2 = test; 
  18.  
  19.   
  20.  
  21. test2.a = 'a2'
  22.  
  23.   
  24.  
  25. test.a === 'a2'// 為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) { 
  2.  
  3. var toString = Object.prototype.toString; 
  4.  
  5. var map = { 
  6.  
  7.     '[object Boolean]'  : 'boolean'
  8.  
  9.     '[object Number]'   : 'number'
  10.  
  11.     '[object String]'   : 'string'
  12.  
  13.     '[object Function]' : 'function'
  14.  
  15.     '[object Array]'    : 'array'
  16.  
  17.     '[object Date]'     : 'date'
  18.  
  19.     '[object RegExp]'   : 'regExp'
  20.  
  21.     '[object Undefined]''undefined'
  22.  
  23.     '[object Null]'     : 'null'
  24.  
  25.     '[object Object]'   : 'object' 
  26.  
  27. }; 
  28.  
  29. return map[toString.call(obj)]; 
  30.  
  31.  

實(shí)現(xiàn)deepClone

對(duì)于非引用值類型的數(shù)值,直接賦值,而對(duì)于引用值類型(object)還需要再次遍歷,遞歸賦值。

  1. function deepClone(data) { 
  2.  
  3. var t = type(data), o, i, ni; 
  4.  
  5. if(t === 'array') { 
  6.  
  7.     o = []; 
  8.  
  9. }else if( t === 'object') { 
  10.  
  11.     o = {}; 
  12.  
  13. }else { 
  14.  
  15.     return data; 
  16.  
  17.  
  18. if(t === 'array') { 
  19.  
  20.     for (i = 0, ni = data.length; i < ni; i++) { 
  21.  
  22.         o.push(deepClone(data[i])); 
  23.  
  24.     } 
  25.  
  26.     return o; 
  27.  
  28. }else if( t === 'object') { 
  29.  
  30.     for( i in data) { 
  31.  
  32.         o[i] = deepClone(data[i]); 
  33.  
  34.     } 
  35.  
  36.     return o; 
  37.  
  38.  
  39.  

這里有個(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ì)返回啥呢?

  1. 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ù)。

  1. function type(obj) { 
  2.  
  3. var toString = Object.prototype.toString; 
  4.  
  5. var map = { 
  6.  
  7.     '[object Boolean]'  : 'boolean'
  8.  
  9.     '[object Number]'   : 'number'
  10.  
  11.     '[object String]'   : 'string'
  12.  
  13.     '[object Function]' : 'function'
  14.  
  15.     '[object Array]'    : 'array'
  16.  
  17.     '[object Date]'     : 'date'
  18.  
  19.     '[object RegExp]'   : 'regExp'
  20.  
  21.     '[object Undefined]''undefined'
  22.  
  23.     '[object Null]'     : 'null'
  24.  
  25.     '[object Object]'   : 'object' 
  26.  
  27. }; 
  28.  
  29. if(obj instanceof Element) { 
  30.  
  31.         return 'element'
  32.  
  33.  
  34. return map[toString.call(obj)]; 
  35.  
  36.  

其它方式?

1. jquery的實(shí)現(xiàn)

詳見https://github.com/jquery/jquery/blob/master/src/core.js

2. underscore的實(shí)現(xiàn)

詳見https://github.com/jashkenas/underscore/blob/master/underscore.js

3. lodash的實(shí)現(xiàn)

詳見https://github.com/lodash/lodash/blob/master/lodash.js

4. JSON實(shí)現(xiàn)

先通過JSON.stringify一下,然后再JSON.parse一下,就能實(shí)現(xiàn)深拷貝。但是數(shù)據(jù)類型只支持基本數(shù)值類型。

  1. var obj = { 
  2.  
  3.     a: 'a',     
  4.  
  5.     b: function(){console.log('b')} 
  6.  
  7.  
  8.   
  9.  
  10. //在JSON.stringify的時(shí)候就會(huì)把function給過濾了。 
  11.  
  12.   
  13.  
  14. JSON.stringify(obj)// "{"a":"a"}"  

小結(jié)

這里大概總結(jié)了一下深拷貝,以及怎么實(shí)現(xiàn)一個(gè)深拷貝。在不同的場(chǎng)景下,要根據(jù)業(yè)務(wù)場(chǎng)景,判斷是否需要使用深拷貝。

參考文獻(xiàn)

winter-JavaScript中的類型 http://www.cnblogs.com/winter-cn/archive/2009/12/07/1618281.html 

責(zé)任編輯:龐桂玉 來源: 前端大全
相關(guān)推薦

2021-07-16 12:33:24

Javascript深拷貝淺拷貝

2020-10-12 08:35:22

JavaScript

2020-06-23 08:41:47

JavaScript開發(fā)技術(shù)

2018-09-26 14:37:17

JavaScript前端編程語言

2023-05-08 09:00:46

JSON深拷貝對(duì)象

2018-05-10 14:20:18

前端JavaScript深拷貝

2025-04-27 09:45:58

JavaScript深拷貝淺拷貝

2024-05-08 08:32:25

架構(gòu)

2024-03-04 08:45:30

JavaScript深度拷貝對(duì)象

2024-08-02 08:43:24

JavaScript開發(fā)者工具箱深拷貝

2017-08-16 13:30:05

Java深拷貝淺拷貝

2021-01-08 06:15:09

深拷貝淺拷貝寫時(shí)拷貝

2023-05-17 08:42:46

深拷貝Golang

2009-05-19 17:28:44

深拷貝淺拷貝clone()

2025-04-17 08:05:00

JavaScript

2024-03-15 15:03:23

2021-09-27 11:07:11

深拷貝淺拷貝內(nèi)存

2022-07-26 08:07:03

Python淺拷貝深拷貝

2024-02-05 22:56:16

C++拷貝開發(fā)

2020-08-03 08:24:26

原型模式拷貝
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)