成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

L - 淺拷貝與深拷貝的實(shí)現(xiàn)

Anshiii / 1670人閱讀

摘要:也就是說(shuō),深拷貝與淺拷貝最主要的區(qū)別在引用類型的拷貝上。方法二遞歸拷貝深拷貝與淺拷貝相比不就是多拷貝幾層的事嘛,這不就是遞歸常干的事嘛。

什么是淺拷貝和深拷貝 淺拷貝

淺拷貝:將一個(gè)對(duì)象自身的屬性拷貝給另一個(gè)對(duì)象,如果源對(duì)象的屬性是基本類型則直接進(jìn)行值賦值,如果是引用類型則進(jìn)行引用賦值,也就是說(shuō)只進(jìn)行一層賦值。

深拷貝

深拷貝:將一個(gè)對(duì)象自身的屬性拷貝給另一個(gè)對(duì)象,如果源對(duì)象的屬性是基本類型則直接進(jìn)行值賦值,如果是引用類型則復(fù)制這個(gè)引用類型,使得目標(biāo)對(duì)象擁有一個(gè)引用類型且和這個(gè)源屬性一模一樣,而非是一個(gè)指針。

也就是說(shuō),深拷貝與淺拷貝最主要的區(qū)別在引用類型的拷貝上。

注意,引用賦值不是淺拷貝??! 引用賦值僅僅只是賦值個(gè)指針,兩個(gè)變量都指向同一內(nèi)存區(qū)域,而淺拷貝是使得兩個(gè)變量分別指向不同的內(nèi)存區(qū)域

如果不懂,可以參考這里 一個(gè)小姐姐的博客

以上不是重點(diǎn)...

淺拷貝的實(shí)現(xiàn) 方法一 使用 for in 遍歷
function shallowCopy(source){
    var target=source instanceof Array ? [] : {};
    for(var i in source){
        if(source.hasOwnProperty(i)){
            target[i]=source[i];
        }
    }
    return target;
}

// 測(cè)試
var obj={a:1,b:[1,2,3],c:function(){console.log("i am c")}}
var tar=shallowCopy(obj)
tar.c()         // "i am c"
obj.a=5
obj.a           // 5
tar.a           // 1
obj.b[0]=10
obj.b           // [10, 2, 3]
tar.b           // [10, 2, 3]

var arr=[1,2,[4,5,6]]
var newArr=shallowCopy(arr)
newArr          // [1, 2, [4,5,6]]
arr[0]=10
arr             // [10, 2, [4,5,6]]
newArr          // [1, 2, [4,5,6]]
arr[2][0]=10
arr             // [1, 2, [10,5,6]]
newArr          // [1, 2, [10,5,6]]
方法二 使用 Object.assign 或 slice、concat

Object.assign

var obj={a:1,b:[1,2,3],c:function(){console.log("i am c")}}
var tar={};
Object.assign(tar,obj);

當(dāng)然這個(gè)方法只適合于對(duì)象類型,如果是數(shù)組可以使用slice和concat方法

Array.prototype.slice

var arr=[1,2,[3,4]];
var newArr=arr.slice(0);

Array.prototype.concat

var arr=[1,2,[3,4]];
var newArr=arr.concat();

測(cè)試同上(assign用對(duì)象測(cè)試、slice concat用數(shù)組測(cè)試),結(jié)合淺拷貝深拷貝的概念來(lái)理解效果更佳

深拷貝的實(shí)現(xiàn) 方法一 JSON黑科技
var obj={a:1,b:[1,2,3],c:function(){console.log("i am c")}}
var tar=JSON.parse(JSON.stringify(obj));

// 測(cè)試
obj.a=5
obj.a     // 5
tar.a     // 1
obj.b[0]=10
obj.b     // [10, 2, 3]
tar.b     // [1, 2, 3]
tar.c()   // Uncaught TypeError: tar.c is not a function

可以看到,無(wú)論是基本類型還是引用類型,兩個(gè)對(duì)象的相同屬性(屬性名相同的屬性)之間并沒(méi)有關(guān)系了,但tar.c()報(bào)錯(cuò)了,我們打印看一下tar有什么console.log(tar) // {a: 1, b: Array(3)}可以看到c方法沒(méi)了,這是和JSON的語(yǔ)法有關(guān),JSON 并不支持函數(shù)類型的數(shù)據(jù)。這也就是這種方法的最大缺陷。

仔細(xì)一看,這并非黑科技,反而倒是有很大缺陷,不過(guò)很好用、效率高,只是在使用前需要稍加注意是否有函數(shù)類型的數(shù)據(jù)罷了。

方法二 遞歸拷貝

深拷貝與淺拷貝相比不就是多拷貝幾層的事嘛,這不就是遞歸常干的事嘛。所以我們就想,在每次拷貝時(shí)都判斷下,該屬性是否是引用類型,如果是我們?cè)龠f歸調(diào)用拷貝方法,否則直接進(jìn)行值賦值。

function deepCopy(obj,tar){
    var tar = tar || {};
    for(var i in obj){
        if(typeof obj[i] === "object"){
            if(obj[i].constructor === Array){
                tar[i] =[];
            }else{
                tar[i] = {};
            }
            deepCopy(obj[i],tar[i]);
          }
        else{
              tar[i] = obj[i];
          }
    }
    return tar;
}

// 使用
var obj={a:1,b:[1,2,3],c:function(){console.log("i am c")}};
var tar={};
deepCopy(obj,tar);
console.log(tar);

測(cè)試同上,你會(huì)驚喜的發(fā)現(xiàn)第一個(gè)方法中的函數(shù)bug沒(méi)了

你看出來(lái)函數(shù)是怎樣進(jìn)行拷貝的了嗎?很簡(jiǎn)單,typeof運(yùn)算符的操作對(duì)象是一個(gè)函數(shù)時(shí),得到的是 "function" 所以在循環(huán)里第一個(gè)if判斷那為false 所以走else分支,在tar[i] = obj[i]這里,函數(shù)是進(jìn)行引用賦值的,如果再造一個(gè)相同的函數(shù)不是不可以,只是不符合思想罷了,函數(shù)占用堆內(nèi)存,如果可以共用當(dāng)然是最好的選擇。

當(dāng)然這個(gè)方法還是有些許不足之處,不夠已經(jīng)很棒了

方法三 更嚴(yán)謹(jǐn)、更優(yōu)雅的實(shí)現(xiàn)

這就需要去讀一些好的源碼了,比如Zepto、JQuery中extend方法的實(shí)現(xiàn)

現(xiàn)學(xué)現(xiàn)賣(mài),如有不足請(qǐng)指出...

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

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

相關(guān)文章

  • 拷貝與深拷貝區(qū)別

    摘要:淺拷貝與深拷貝一數(shù)據(jù)類型數(shù)據(jù)分為基本數(shù)據(jù)類型,和對(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ù)類...

    jsyzchen 評(píng)論0 收藏0
  • JavaScript中拷貝與深拷貝

    摘要:所以,深拷貝是對(duì)對(duì)象以及對(duì)象的所有子對(duì)象進(jìn)行拷貝實(shí)現(xiàn)方式就是遞歸調(diào)用淺拷貝對(duì)于深拷貝的對(duì)象,改變?cè)磳?duì)象不會(huì)對(duì)得到的對(duì)象有影響。 為什么會(huì)有淺拷貝與深拷貝什么是淺拷貝與深拷貝如何實(shí)現(xiàn)淺拷貝與深拷貝好了,問(wèn)題出來(lái)了,那么下面就讓我們帶著這幾個(gè)問(wèn)題去探究一下吧! 如果文章中有出現(xiàn)紕漏、錯(cuò)誤之處,還請(qǐng)看到的小伙伴多多指教,先行謝過(guò) 以下↓ 數(shù)據(jù)類型在開(kāi)始了解 淺拷貝 與 深拷貝 之前,讓我們先...

    546669204 評(píng)論0 收藏0
  • JavaScript中拷貝與深拷貝

    摘要:所以,深拷貝是對(duì)對(duì)象以及對(duì)象的所有子對(duì)象進(jìn)行拷貝實(shí)現(xiàn)方式就是遞歸調(diào)用淺拷貝對(duì)于深拷貝的對(duì)象,改變?cè)磳?duì)象不會(huì)對(duì)得到的對(duì)象有影響。 上一篇 JavaScript中的繼承 前言 文章開(kāi)始之前,讓我們先思考一下這幾個(gè)問(wèn)題: 為什么會(huì)有淺拷貝與深拷貝 什么是淺拷貝與深拷貝 如何實(shí)現(xiàn)淺拷貝與深拷貝 好了,問(wèn)題出來(lái)了,那么下面就讓我們帶著這幾個(gè)問(wèn)題去探究一下吧! 如果文章中有出現(xiàn)紕漏、錯(cuò)誤之處...

    AZmake 評(píng)論0 收藏0
  • 關(guān)于js拷貝與深拷貝

    摘要:原文地址淺拷貝和深拷貝只針對(duì)像這樣的復(fù)雜對(duì)象的簡(jiǎn)單來(lái)說(shuō),淺拷貝只拷貝一層對(duì)象的屬性,而深拷貝則遞歸拷貝了所有層級(jí)。淺拷貝通過(guò)來(lái)實(shí)現(xiàn)淺拷貝。 原文地址:http://www.silenceboy.com/201... 淺拷貝和深拷貝只針對(duì)像Object, Array這樣的復(fù)雜對(duì)象的.簡(jiǎn)單來(lái)說(shuō),淺拷貝只拷貝一層對(duì)象的屬性,而深拷貝則遞歸拷貝了所有層級(jí)。 淺拷貝 通過(guò) Object.ass...

    summerpxy 評(píng)論0 收藏0
  • 20170606-拷貝與深拷貝

    摘要:什么是深拷貝,什么是淺拷貝中的淺拷貝與深拷貝是針對(duì)復(fù)雜數(shù)據(jù)類型引用類型的復(fù)制問(wèn)題。 什么是深拷貝,什么是淺拷貝 JS中的淺拷貝與深拷貝是針對(duì)復(fù)雜數(shù)據(jù)類型(引用類型)的復(fù)制問(wèn)題。 淺拷貝:淺拷貝是拷貝引用(拷貝地址),拷貝后兩個(gè)變量指向的是同一塊內(nèi)存空間 深拷貝:會(huì)在內(nèi)存中開(kāi)辟一塊新的內(nèi)存空間,它不僅將原對(duì)象的各個(gè)屬性逐個(gè)復(fù)制過(guò)去,而且將原對(duì)象各個(gè)屬性所包含的內(nèi)容也依次采用深復(fù)制的方法...

    Kerr1Gan 評(píng)論0 收藏0

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

0條評(píng)論

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