中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Javascript中深拷貝的原理是什么

發布時間:2021-07-01 16:49:53 來源:億速云 閱讀:188 作者:Leah 欄目:web開發

Javascript中深拷貝的原理是什么,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

為啥要用深拷貝?

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

看一個具體的例子

// 給test賦值了一個對象  var test = {  a: 'a',  b: 'b'  };     // 將test賦值給test2  // 此時test和test2是共享了同一塊內存對象,這也就是淺拷貝  var test2 = test;     test2.a = 'a2';     test.a === 'a2'// 為true

圖解:

Javascript中深拷貝的原理是什么

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

實現

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

判斷javascript類型

javascript中有以下基本類型

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

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

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)];  }

實現deepClone

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

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

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

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

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

淺拷貝?

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

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

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

Element類型

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

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

答案是[object HTMLDivElement]

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

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)];  }

其它方式?

JSON實現

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

var obj = {      a: 'a',          b: function(){console.log('b')}  }     //在JSON.stringify的時候就會把function給過濾了。     JSON.stringify(obj)// "{"a":"a"}"

關于Javascript中深拷貝的原理是什么問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

新安县| 福建省| 隆安县| 玛曲县| 赣州市| 托克托县| 馆陶县| 白水县| 广安市| 西乌珠穆沁旗| 碌曲县| 荔浦县| 亚东县| 霍山县| 荣昌县| 科尔| 松原市| 邹城市| 延安市| 苍溪县| 宝鸡市| 乡城县| 景洪市| 罗江县| 颍上县| 青田县| 镶黄旗| 宽甸| 绥阳县| 广德县| 阿拉善盟| 民勤县| 若尔盖县| 义马市| 满洲里市| 纳雍县| 大城县| 玉溪市| 扬州市| 榆林市| 娱乐|