成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Javascript深拷貝

開發 前端
javascript深拷貝是初學者甚至有經驗的開發者,都會經常遇到問題,并不能很好的理解javascript的深拷貝。

[[192119]]

javascript深拷貝是初學者甚至有經驗的開發者,都會經常遇到問題,并不能很好的理解javascript的深拷貝。

深拷貝(deepClone)?

與深拷貝相對的就是淺拷貝,很多初學者在接觸這個感念的時候,是很懵逼的。 

[[192120]] 

為啥要用深拷貝?

在很多情況下,我們都需要給變量賦值,給內存地址賦予一個值,但是在賦值引用值類型的時候,只是共享一個內存區域,導致賦值的時候,還跟之前的值保持一直性。

看一個具體的例子

  1. // 給test賦值了一個對象 
  2.  
  3. var test = { 
  4.  
  5. a: 'a'
  6.  
  7. b: 'b' 
  8.  
  9. }; 
  10.  
  11.   
  12.  
  13. // 將test賦值給test2 
  14.  
  15. // 此時test和test2是共享了同一塊內存對象,這也就是淺拷貝 
  16.  
  17. var test2 = test; 
  18.  
  19.   
  20.  
  21. test2.a = 'a2'
  22.  
  23.   
  24.  
  25. test.a === 'a2'// 為true  

圖解: 

 

這下就很好理解為什么引用值類型數據相互影響問題。

實現

實現一個深拷貝函數,就不得不說javascript的數值類型。

判斷javascript類型

javascript中有以下基本類型

類型 描述
undefined undefined類型只有一個值undefined,它是變量未被賦值時的值
null null類型也只有一個值null, 它是一個空的對象引用
Boolean Boolean有兩種取值true和false
String 它表示文本信息
Number 它表示數字信息
Object 它是一系列屬性的無序集合, 包括函數Function和數組Array

使用typeof是無法判斷function和array的,這里使用Object.prototype.toString方法。 默認情況下,每個對象都會從Object上繼承到toString()方法,如果這個方法沒有被這個對象自身或者更接近的上層原型上的同名方法覆蓋(遮蔽),則調用該對象的toString()方法時會返回”[object type]”,這里的字符串type表示了一個對象類型

  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.  

實現deepClone

對于非引用值類型的數值,直接賦值,而對于引用值類型(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.  

這里有個點大家要注意下,對于function類型,博主這里是直接賦值的,還是共享一個內存值。這是因為函數更多的是完成某些功能,有個輸入值和返回值,而且對于上層業務而言更多的是完成業務功能,并不需要真正將函數深拷貝。

但是function類型要怎么拷貝呢?

其實博主只想到了用new來操作一下,但是function就會執行一遍,不敢想象會有什么執行結果哦!o(╯□╰)o!其它暫時還沒有什么好的想法,歡迎大家指導哦!

到這里差不多也就實現完了深拷貝,又有人覺的怎么沒有實現淺拷貝呢?

淺拷貝?

對于淺拷貝而言,可以理解為只操作一個共同的內存區域!這里會存在危險!(。﹏。*) 。

如果直接操作這個共享的數據,不做控制的話,會經常出現數據異常,被其它部分更改。所以應該不要直接操作數據源,給數據源封裝一些方法,來對數據來進行CURD操作。

到這里估計就差不多了,但是作為一個前端,不僅僅考慮javascript本身,還得考慮到dom、瀏覽器等。

Element類型

來看下面代碼,結果會返回啥呢?

  1. Object.prototype.toString.call(document.getElementsByTagName('div')[0]) 

答案是[object HTMLDivElement]

有時候保存了dom元素, 一不小心進行深拷貝,上面的深拷貝函數就缺少了對Element元素的判斷。而判斷Element元素要使用instanceof來判斷。因為對于不同的標簽,tostring會返回對應不同的標簽的構造函數。

  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的實現

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

2. underscore的實現

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

3. lodash的實現

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

4. JSON實現

先通過JSON.stringify一下,然后再JSON.parse一下,就能實現深拷貝。但是數據類型只支持基本數值類型。

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

小結

這里大概總結了一下深拷貝,以及怎么實現一個深拷貝。在不同的場景下,要根據業務場景,判斷是否需要使用深拷貝。

參考文獻

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

責任編輯:龐桂玉 來源: 前端大全
相關推薦

2021-07-16 12:33:24

Javascript深拷貝淺拷貝

2020-10-12 08:35:22

JavaScript

2020-06-23 08:41:47

JavaScript開發技術

2023-05-08 09:00:46

JSON深拷貝對象

2018-09-26 14:37:17

JavaScript前端編程語言

2018-05-10 14:20:18

前端JavaScript深拷貝

2025-04-27 09:45:58

JavaScript深拷貝淺拷貝

2024-05-08 08:32:25

架構

2017-08-16 13:30:05

Java深拷貝淺拷貝

2024-08-02 08:43:24

JavaScript開發者工具箱深拷貝

2021-01-08 06:15:09

深拷貝淺拷貝寫時拷貝

2024-03-04 08:45:30

JavaScript深度拷貝對象

2023-05-17 08:42:46

深拷貝Golang

2009-05-19 17:28:44

深拷貝淺拷貝clone()

2025-04-17 08:05:00

JavaScript

2021-09-27 11:07:11

深拷貝淺拷貝內存

2024-03-15 15:03:23

2022-07-26 08:07:03

Python淺拷貝深拷貝

2024-02-05 22:56:16

C++拷貝開發

2020-08-03 08:24:26

原型模式拷貝
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 成人免费观看男女羞羞视频 | av在线免费观看网址 | 99精品视频在线观看免费播放 | 日韩av成人在线 | 麻豆国产精品777777在线 | 欧美精品一区二区三区在线四季 | 一区二区av | 天堂国产 | 国产高清精品在线 | 欧美一级二级视频 | 欧美亚洲国产日韩 | 欧美一区二区三区免费在线观看 | 日韩aⅴ片| 日韩一区二区在线视频 | 午夜国产羞羞视频免费网站 | 亚洲精品大片 | 四色永久 | 亚洲欧美一区二区三区国产精品 | 成人性视频免费网站 | 国产亚洲精品一区二区三区 | 欧美电影免费观看高清 | xxx视频| 午夜精品一区 | 欧美性猛片aaaaaaa做受 | 欧美久久久电影 | 在线中文字幕视频 | 欧美八区| 99久久久无码国产精品 | 97国产爽爽爽久久久 | 久久精品国产免费看久久精品 | 国产精品美女 | 亚洲成av | 国产乱码精品一品二品 | 狠狠亚洲 | 国产在线拍偷自揄拍视频 | 91精品国产99 | 日韩成人av在线 | 国产在线播放一区二区三区 | chinese中国真实乱对白 | 成人av网页 | 日韩欧美在线观看 |