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

資訊專欄INFORMATION COLUMN

深拷貝 vs 淺拷貝

sugarmo / 1517人閱讀

摘要:那么如何切斷和之間的關(guān)系呢,可以拷貝一份的數(shù)據(jù),根據(jù)拷貝的層級不同可以分為淺拷貝和深拷貝,淺拷貝就是只進(jìn)行一層拷貝,深拷貝就是無限層級拷貝。

深拷貝 vs 淺拷貝

深拷貝和淺拷貝都是針對的引用類型,JS中的變量類型分為值類型(基本類型)和引用類型;對值類型進(jìn)行復(fù)制操作會對進(jìn)行一份拷貝,而對引用類型賦值,則會進(jìn)行地址的拷貝,最終兩個變量指向同一份數(shù)據(jù)。

// 基本類型
var a = 1;
var b = a;
a = 2;
console.log(a, b); // 2, 1 ,a b指向不同的數(shù)據(jù)

// 引用類型指向同一份數(shù)據(jù)
var a = {c: 1};
var b = a;
a.c = 2;
console.log(a.c, b.c); // 2, 2 全是2,a b指向同一份數(shù)據(jù)

對于引用類型,會導(dǎo)致a b指向同一份數(shù)據(jù),此時如果對其中一個進(jìn)行修改,就會影響到另外一個,有時候這可能不是我們想要的結(jié)果,如果對這種現(xiàn)象不清楚的話,還可能造成不必要的bug。那么如何切斷a和b之間的關(guān)系呢,可以拷貝一份a的數(shù)據(jù),根據(jù)拷貝的層級不同可以分為淺拷貝和深拷貝,淺拷貝就是只進(jìn)行一層拷貝,深拷貝就是無限層級拷貝。

深復(fù)制和淺復(fù)制最根本的區(qū)別在于是否是真正獲取了一個對象的復(fù)制實體,而不是引用

深復(fù)制在計算機(jī)中開辟了一塊內(nèi)存地址用于存放復(fù)制的對象,

淺復(fù)制僅僅是指向被復(fù)制的內(nèi)存地址,如果原地址中對象被改變了,那么淺復(fù)制出來的對象也會相應(yīng)改變。

var a1 = {b: {c: {}};

var a2 = shallowClone(a1); // 淺拷貝
a2.b.c === a1.b.c // true

var a3 = clone(a1); // 深拷貝
a3.b.c === a1.b.c // false
所謂的淺復(fù)制,只是拷貝了基本類型的數(shù)據(jù),而引用類型數(shù)據(jù),復(fù)制后也是會發(fā)生引用,我們把這種拷貝叫做“(淺復(fù)制)淺拷貝”。Object.assign({}, obj1, obj2)
淺拷貝的實現(xiàn)
function shallowClone(source) {
    var target = {};
    for(var i in source) {
        if (source.hasOwnProperty(i)) {
            target[i] = source[i];
        }
    }
    return target;
}
深拷貝的實現(xiàn)

深拷貝的問題其實可以分解成兩個問題,淺拷貝+遞歸,什么意思呢?假設(shè)我們有如下數(shù)據(jù)

var a1 = {b: {c: {d: 1}};

只需稍加改動上面淺拷貝的代碼即可,注意區(qū)別

function clone(source) {
    var target = {};
    for(var i in source) {
        if (source.hasOwnProperty(i)) {
            if (typeof source[i] === "object") {
                target[i] = clone(source[i]); // 注意這里
            } else {
                target[i] = source[i];
            }
        }
    }

    return target;
}

其實上面的代碼問題太多了,先來舉幾個例子吧

沒有對參數(shù)做檢驗

function isObject(x) {
    return Object.prototype.toString.call(x) === "[object Object]";
}
function clone(source) {
    if (!isObject(source)) return source;

    // xxx
}

判斷是否對象的邏輯不夠嚴(yán)謹(jǐn)

沒有考慮數(shù)組的兼容

遞歸方法最大的問題在于爆棧,當(dāng)數(shù)據(jù)的層次很深是就會棧溢出

方法: 用系統(tǒng)自帶的JSON來做深拷貝的例子,下面來看下代碼實現(xiàn)

function cloneJSON(source) {
    return JSON.parse(JSON.stringify(source));
}

但是cloneJSON也有缺點,它的內(nèi)部也是使用遞歸的方式
cloneJSON(createData(10000)); // Maximum call stack size exceeded

既然是用了遞歸,那循環(huán)引用呢?并沒有因為死循環(huán)而導(dǎo)致棧溢出啊,原來是JSON.stringify內(nèi)部做了循環(huán)引用的檢測,正是我們上面提到破解循環(huán)引用的第一種方法:循環(huán)檢測

var a = {};
a.a = a;

cloneJSON(a) // Uncaught TypeError: Converting circular structure to JSON

如何復(fù)制對象而不發(fā)生引用呢,對于數(shù)組,ES6我們復(fù)制有新的兩種方法,不會發(fā)生引用。
第一種:Array.from(要復(fù)制的數(shù)組);

var arr1=[1,2,3];
var arr2=Array.from(arr1);
arr1.push(4);
alert(arr1);  //1234
alert(arr2);  //123
arr2.push(5);
alert(arr1);  //1234
alert(arr2);  //1235

第二種:...

var arr1=[1,2,3];
var arr2=[...arr1];
arr1.push(4);
alert(arr1);  //1234
alert(arr2);  //123
arr2.push(5);
alert(arr1);  //1234
alert(arr2);  //1235

第二種這個方法也可以用在函數(shù)的行參上面。

function show(...arr1){  //直接來復(fù)制arguments這個偽數(shù)組,讓它變成真正的數(shù)組,從而擁有數(shù)組的方法。
  alert(arr1); //1234
  arr1.push(5);
  alert(arr1); //12345
}
show(1,2,3,4)

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/100128.html

相關(guān)文章

  • javascript的拷貝VS拷貝

    摘要:深拷貝淺拷貝本文主要對深拷貝淺拷貝的解釋及實現(xiàn)做一下簡單記錄。之所以會有深拷貝與淺拷貝之分,是因為不同數(shù)據(jù)類型的數(shù)據(jù)在內(nèi)存中的存儲區(qū)域不一樣。但注意,只能做一層屬性的淺拷貝。 深拷貝VS淺拷貝 本文主要對深拷貝&淺拷貝的解釋及實現(xiàn)做一下簡單記錄。原文鏈接,歡迎star。 之所以會有深拷貝與淺拷貝之分,是因為不同數(shù)據(jù)類型的數(shù)據(jù)在內(nèi)存中的存儲區(qū)域不一樣。 堆和棧是計算機(jī)中劃分出來用來存儲的...

    Nekron 評論0 收藏0
  • JavaScript·隨記 拷貝 vs. 拷貝

    摘要:而在這個運算符的相關(guān)用例中,往往會涉及到其他知識點,深拷貝和淺拷貝就是其中之一。即對象的淺拷貝會對主對象的值進(jìn)行拷貝,而該值有可能是一個指針,指向內(nèi)存中的同一個對象。,可以看到深拷貝和淺拷貝是對復(fù)制引用類型變量而言的。 在ES6的系列文章中,基本都會提到Spread——擴(kuò)展運算符(...)。而在這個運算符的相關(guān)用例中,往往會涉及到其他知識點,深拷貝和淺拷貝就是其中之一。 背景知識 在討...

    RyanQ 評論0 收藏0
  • 拷貝拷貝

    摘要:二淺拷貝與深拷貝深拷貝和淺拷貝是只針對和這樣的引用數(shù)據(jù)類型的。淺拷貝是按位拷貝對象,它會創(chuàng)建一個新對象,這個對象有著原始對象屬性值的一份精確拷貝。對于字符串?dāng)?shù)字及布爾值來說不是或者對象,會拷貝這些值到新的數(shù)組里。 一、數(shù)據(jù)類型 數(shù)據(jù)分為基本數(shù)據(jù)類型(String, Number, Boolean, Null, Undefined,Symbol)和對象數(shù)據(jù)類型。 基本數(shù)據(jù)類型的特點:直...

    hzc 評論0 收藏0
  • 拷貝拷貝

    摘要:二淺拷貝與深拷貝深拷貝和淺拷貝是只針對和這樣的引用數(shù)據(jù)類型的。淺拷貝是按位拷貝對象,它會創(chuàng)建一個新對象,這個對象有著原始對象屬性值的一份精確拷貝。對于字符串?dāng)?shù)字及布爾值來說不是或者對象,會拷貝這些值到新的數(shù)組里。 一、數(shù)據(jù)類型 數(shù)據(jù)分為基本數(shù)據(jù)類型(String, Number, Boolean, Null, Undefined,Symbol)和對象數(shù)據(jù)類型。 基本數(shù)據(jù)類型的特點:直...

    史占廣 評論0 收藏0

發(fā)表評論

0條評論

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