国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

javascript深拷貝(deepClone)

hatlonely / 1126人閱讀

摘要:實現實現一個深拷貝函數,就不得不說的數值類型。類型來看下面代碼,結果會返回啥呢答案是有時候保存了元素,一不小心進行深拷貝,上面的深拷貝函數就缺少了對元素的判斷。在不同的場景下,要根據業務場景,判斷是否需要使用深拷貝。

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

深拷貝(deepClone)?

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

為啥要用深拷貝?

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

// 給test賦值了一個對象
var test = {
    a: "a",
    b: "b"
};

// 將test賦值給test2
// 此時test和test2是共享了同一塊內存對象,這也就是淺拷貝
var test2 = test;

test2.a = "a2";

test.a === "a2"http:// 為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) {
    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)];
}
其它方式?

jquery的實現
詳見https://github.com/jquery/jqu...

underscore的實現
詳見https://github.com/jashkenas/...

lodash的實現
詳見https://github.com/lodash/lod...

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

var obj = {
    a: "a",    
    b: function(){console.log("b")}
}

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

JSON.stringify(obj)// "{"a":"a"}"
小結

這里大概總結了一下深拷貝,以及怎么實現一個深拷貝。在不同的場景下,要根據業務場景,判斷是否需要使用深拷貝。
原文鏈接 http://xiaoqiang730730.github...

參考文獻

winter-JavaScript中的類型
http://www.cnblogs.com/winter...

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/80149.html

相關文章

  • JavaScript中淺拷貝拷貝的區別和實現

    摘要:要理解中淺拷貝和深拷貝的區別,首先要明白的數據類型有兩種數據類型,基礎數據類型和引用數據類型基礎數據類型保存在棧內存中的簡單數據段,有,,,,引用數據類型,對象,保存在堆內存空間中存放在棧內存中與變量名與內存地址存儲在棧內存中,與作為對象存 要理解 JavaScript中淺拷貝和深拷貝的區別,首先要明白JavaScript的數據類型 JavaScript有兩種數據類型,基礎數據類型和引...

    wenshi11019 評論0 收藏0
  • JavaScript中的淺拷貝拷貝

    摘要:在中可以通過添加一個參數來實現遞歸,調用就可以實現一個深拷貝。利用序列化實現一個深拷貝 在JavaScript中,對于Object和Array這類引用類型值,當從一個變量向另一個變量復制引用類型值時,這個值的副本其實是一個指針,兩個變量指向同一個堆對象,改變其中一個變量,另一個也會受到影響。 這種拷貝分為兩種情況:拷貝引用和拷貝實例,也就是我們說的淺拷貝和深拷貝 淺拷貝(shallow...

    ernest.wang 評論0 收藏0
  • 淺談JavaScript拷貝實現的方法

    摘要:相信人很多學習的過程中都踩了深拷貝和淺拷貝的坑,深拷貝和淺拷貝的區別我就不再贅述了,今天我來寫一下我自己實現深拷貝的各種方法。中的深拷貝也是用類似方法實現。 相信人很多學習js的過程中都踩了深拷貝和淺拷貝的坑,深拷貝和淺拷貝的區別我就不再贅述了,今天我來寫一下我自己實現深拷貝的各種方法。 比較簡單的拷貝方式可以借用瀏覽器的Json對象去實現,先把對象轉化為json字符串,在解析回對...

    Vicky 評論0 收藏0
  • 復習Javascript專題(四):js中的拷貝

    摘要:基本數據類型的復制很簡單,就是賦值操作,所以深淺拷貝也是針對,這類引用類型數據。它會拋棄對象的。另外,查資料過程中還看到這么一個詞結構化克隆算法還有這一篇資料也有參考,也寫得比較詳細了的深淺拷貝 基本數據類型的復制很簡單,就是賦值操作,所以深淺拷貝也是針對Object,Array這類引用類型數據。 淺拷貝對于字符串來說,是值的復制,而對于對象來說則是對對象地址的復制;而深拷貝的話,它不...

    MobService 評論0 收藏0
  • 拷貝

    摘要:深復制實現代碼如下第一種方法通過遞歸解析解決第二種方法通過解析解決作者六師兄鏈接原生深拷貝的實現處理未輸入新對象的情況通過方法構造新的對象 深淺拷貝針對的是 對象類型,如果是字符串的數組用[...arr],還是不會影響 要區分針對數組的深淺拷貝(默認情況為里面沒有對象的數組),與針對對象的深淺拷貝 JavaScript數組深拷貝和淺拷貝的兩種方法 let a1 = [1, 2]; ...

    Karrdy 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<