亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

深拷貝 vs 淺拷貝

sugarmo / 1561人閱讀

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

深拷貝 vs 淺拷貝

深拷貝和淺拷貝都是針對(duì)的引用類型,JS中的變量類型分為值類型(基本類型)和引用類型;對(duì)值類型進(jìn)行復(fù)制操作會(huì)對(duì)進(jìn)行一份拷貝,而對(duì)引用類型賦值,則會(huì)進(jìn)行地址的拷貝,最終兩個(gè)變量指向同一份數(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ù)

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

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

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

淺復(fù)制僅僅是指向被復(fù)制的內(nèi)存地址,如果原地址中對(duì)象被改變了,那么淺復(fù)制出來(lái)的對(duì)象也會(huì)相應(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ù)制后也是會(huì)發(fā)生引用,我們把這種拷貝叫做“(淺復(fù)制)淺拷貝”。Object.assign({}, obj1, obj2)
淺拷貝的實(shí)現(xiàn)
function shallowClone(source) {
    var target = {};
    for(var i in source) {
        if (source.hasOwnProperty(i)) {
            target[i] = source[i];
        }
    }
    return target;
}
深拷貝的實(shí)現(xiàn)

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

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

只需稍加改動(dòng)上面淺拷貝的代碼即可,注意區(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í)上面的代碼問(wèn)題太多了,先來(lái)舉幾個(gè)例子吧

沒有對(duì)參數(shù)做檢驗(yàn)

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

    // xxx
}

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

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

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

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

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

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

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

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

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

如何復(fù)制對(duì)象而不發(fā)生引用呢,對(duì)于數(shù)組,ES6我們復(fù)制有新的兩種方法,不會(huì)發(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

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

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

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/100128.html

相關(guān)文章

  • javascript的拷貝VS拷貝

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

    Nekron 評(píng)論0 收藏0
  • JavaScript·隨記 拷貝 vs. 拷貝

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

    RyanQ 評(píng)論0 收藏0
  • 拷貝拷貝

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

    hzc 評(píng)論0 收藏0
  • 拷貝拷貝

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

    史占廣 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<