乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Javascript 深拷貝

       melon1024 2016-08-28


      作者:伯樂在線專欄作者 - 前端-小強

      鏈接:http://web./87627/

      點擊 → 了解如何加入專欄作者


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


      深拷貝(deepClone)?


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



      為啥要用深拷貝?


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


      看一個具體的例子


      // 給test賦值了一個對象

      var test = {

      a: 'a',

      b: 'b'

      };

       

      // 將test賦值給test2

      // 此時test和test2是共享了同一塊內(nèi)存對象,這也就是淺拷貝

      var test2 = test;

       

      test2.a = 'a2';

       

      test.a === 'a2'// 為true


      圖解:



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


      實現(xiàn)


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


      判斷javascript類型


      javascript中有以下基本類型


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


      使用typeof是無法判斷function和array的,這里使用Object.prototype.toString方法。 默認情況下,每個對象都會從Object上繼承到toString()方法,如果這個方法沒有被這個對象自身或者更接近的上層原型上的同名方法覆蓋(遮蔽),則調(diào)用該對象的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)];

      }


       實現(xiàn)deepClone


      對于非引用值類型的數(shù)值,直接賦值,而對于引用值類型(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類型,博主這里是直接賦值的,還是共享一個內(nèi)存值。這是因為函數(shù)更多的是完成某些功能,有個輸入值和返回值,而且對于上層業(yè)務(wù)而言更多的是完成業(yè)務(wù)功能,并不需要真正將函數(shù)深拷貝。


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


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


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


      淺拷貝?


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


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


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


      Element類型


      來看下面代碼,結(jié)果會返回啥呢?


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


      答案是[object HTMLDivElement]


      有時候保存了dom元素, 一不小心進行深拷貝,上面的深拷貝函數(shù)就缺少了對Element元素的判斷。而判斷Element元素要使用instanceof來判斷。因為對于不同的標簽,tostring會返回對應(yīng)不同的標簽的構(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)];

      }


      其它方式?


      1. jquery的實現(xiàn)


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


      2. underscore的實現(xiàn)


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


      3. lodash的實現(xiàn)


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


      4. JSON實現(xiàn)


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


      var obj = {

          a: 'a',    

          b: function(){console.log('b')}

      }

       

      //在JSON.stringify的時候就會把function給過濾了。

       

      JSON.stringify(obj)// '{'a':'a'}'


      小結(jié)


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


      參考文獻


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


      專欄作者簡介 ( 點擊 → 加入專欄作者 

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多