日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
Javascript深拷貝

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

讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來(lái)自于我們對(duì)這個(gè)行業(yè)的熱愛。我們立志把好的技術(shù)通過(guò)有效、簡(jiǎn)單的方式提供給客戶,將通過(guò)不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長(zhǎng)期合作伙伴,公司提供的服務(wù)項(xiàng)目有:域名與空間、虛擬空間、營(yíng)銷軟件、網(wǎng)站建設(shè)、梨林網(wǎng)站維護(hù)、網(wǎng)站推廣。

深拷貝(deepClone)?

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

為啥要用深拷貝?

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

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

 
 
 
 
  1. // 給test賦值了一個(gè)對(duì)象
  2. var test = {
  3. a: 'a',
  4. b: 'b'
  5. };
  6.  
  7. // 將test賦值給test2
  8. // 此時(shí)test和test2是共享了同一塊內(nèi)存對(duì)象,這也就是淺拷貝
  9. var test2 = test;
  10.  
  11. test2.a = 'a2';
  12.  
  13. test.a === 'a2'// 為true 

圖解:

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

實(shí)現(xiàn)

實(shí)現(xiàn)一個(gè)深拷貝函數(shù),就不得不說(shuō)javascript的數(shù)值類型。

判斷javascript類型

javascript中有以下基本類型

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

使用typeof是無(wú)法判斷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. var toString = Object.prototype.toString;
  3. var map = {
  4.     '[object Boolean]'  : 'boolean',
  5.     '[object Number]'   : 'number',
  6.     '[object String]'   : 'string',
  7.     '[object Function]' : 'function',
  8.     '[object Array]'    : 'array',
  9.     '[object Date]'     : 'date',
  10.     '[object RegExp]'   : 'regExp',
  11.     '[object Undefined]': 'undefined',
  12.     '[object Null]'     : 'null',
  13.     '[object Object]'   : 'object'
  14. };
  15. return map[toString.call(obj)];

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

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

 
 
 
 
  1. function deepClone(data) {
  2. var t = type(data), o, i, ni;
  3. if(t === 'array') {
  4.     o = [];
  5. }else if( t === 'object') {
  6.     o = {};
  7. }else {
  8.     return data;
  9. }
  10. if(t === 'array') {
  11.     for (i = 0, ni = data.length; i < ni; i++) {
  12.         o.push(deepClone(data[i]));
  13.     }
  14.     return o;
  15. }else if( t === 'object') {
  16.     for( i in data) {
  17.         o[i] = deepClone(data[i]);
  18.     }
  19.     return o;
  20. }

這里有個(gè)點(diǎn)大家要注意下,對(duì)于function類型,博主這里是直接賦值的,還是共享一個(gè)內(nèi)存值。這是因?yàn)楹瘮?shù)更多的是完成某些功能,有個(gè)輸入值和返回值,而且對(duì)于上層業(yè)務(wù)而言更多的是完成業(yè)務(wù)功能,并不需要真正將函數(shù)深拷貝。

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

其實(shí)博主只想到了用new來(lái)操作一下,但是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ù)源封裝一些方法,來(lái)對(duì)數(shù)據(jù)來(lái)進(jìn)行CURD操作。

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

Element類型

來(lái)看下面代碼,結(jié)果會(huì)返回啥呢?

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

答案是[object HTMLDivElement]

有時(shí)候保存了dom元素, 一不小心進(jìn)行深拷貝,上面的深拷貝函數(shù)就缺少了對(duì)Element元素的判斷。而判斷Element元素要使用instanceof來(lái)判斷。因?yàn)閷?duì)于不同的標(biāo)簽,tostring會(huì)返回對(duì)應(yīng)不同的標(biāo)簽的構(gòu)造函數(shù)。

 
 
 
 
  1. function type(obj) {
  2. var toString = Object.prototype.toString;
  3. var map = {
  4.     '[object Boolean]'  : 'boolean',
  5.     '[object Number]'   : 'number',
  6.     '[object String]'   : 'string',
  7.     '[object Function]' : 'function',
  8.     '[object Array]'    : 'array',
  9.     '[object Date]'     : 'date',
  10.     '[object RegExp]'   : 'regExp',
  11.     '[object Undefined]': 'undefined',
  12.     '[object Null]'     : 'null',
  13.     '[object Object]'   : 'object'
  14. };
  15. if(obj instanceof Element) {
  16.         return 'element';
  17. }
  18. return map[toString.call(obj)];

其它方式?

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)

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

 
 
 
 
  1. var obj = {
  2.     a: 'a',    
  3.     b: function(){console.log('b')}
  4. }
  5.  
  6. //在JSON.stringify的時(shí)候就會(huì)把function給過(guò)濾了。
  7.  
  8. 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


當(dāng)前名稱:Javascript深拷貝
分享網(wǎng)址:http://m.5511xx.com/article/djicpje.html