欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript最完整的深淺拷貝實現方式詳解

 更新時間:2022年02月28日 15:19:00   作者:Beannnnnnn  
這篇文章主要為大家詳細介紹了JavaScript最完整的深淺拷貝實現方式,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助

深淺拷貝:

內存中一共分為棧內存和堆內存兩大區(qū)域,所謂深淺拷貝主要是對js引用類型數據進行拷貝一份,淺拷貝就是引用類型數據相互賦值之后,例obj1=obj2;如果后面的操作中修改obj1或者obj2,這個時候數據是會進行相應的變化的,因為在內存中引用類型數據是存儲在堆內存中,堆內存中存放的是引用類型的值,同時會有一個指針地址指向棧內存,兩個引用類型數據地址一樣,如果其中一個發(fā)生變化另外一個都會有影響;而深拷貝則不會,深拷貝是會在堆內存中重新開辟一塊空間進行存放;

簡單來說就是B復制了A,如果A發(fā)生了改變,如果B隨之變化,那么是淺拷貝,如果B并沒有發(fā)生變化,則是深拷貝。

基本類型拷貝

let a = 1;
let b = a;
b = 2;
console.log(a);//1
console.log(b);//2

a,b都是屬于基本類型,基本類型的復制是不會影響對方的,因為基本類型是每一次創(chuàng)建變量都會在棧內存中開辟一塊內存,用來存放值,所以對基本類型進行拷貝是不會對另外一個變量有影響的,屬于深拷貝。

數組拷貝 

concat() slice()

//  concat()
let list = ['a','b','c'];
let list2 = list.concat();
list2.push('d')
console.log(list);//['a','b','c']
console.log(list2);//['a','b','c','d']
//  slice()
let list = ['a','b','c'];
let list2 = list.slice();
list2.push('d')
console.log(list);//['a','b','c']
console.log(list2);//['a','b','c','d']

上面兩種方法只能實現數組類型里面的單層深拷貝,如果是多層無法實現深拷貝。

//二維數組
let list = ['a','b','c',['d','e','f']];
let list2 = list.concat();
list2[3][0] = 'a';
console.log(list);
console.log(list2);

可以看到原二維數組的值也發(fā)生了變化,說明沒有實現深拷貝。

由此總結,concat和slice只能實現一維數組的深拷貝,不能對多維數組進行深拷貝,所以并不是一個完美的深拷貝方式。

對象拷貝

new Object()

let a = {id:1,name:'a',obj:{id:999}};
let b = new Object();
b.id = a.id;
b.name = a.name;
b.obj = a.obj;
a.name = 'b';
a.obj.id = 888;
console.log(a);
console.log(b);

 

a.name更改并沒有影響到b.name,好像可以看作深拷貝,但第二層obj里面里面的id隨之更改了,因此其實并不是深拷貝。

Object.assign

let a = {id:1,name:'a',obj:{id:999}};
function fun(obj){
    let o = {};
    Object.assign(o,obj);
    return o;
}
let a2 = fun(a);
a2.name ='a2';
a2.obj.id = 888;
console.log(a);
console.log(a2);

以上兩種方法,對于一層對象都能實現深拷貝,但對于多層對象則無法實現,因此也不是一種完美的深拷貝方式。

JSON.parse(JSON.stringify( ))

let a = {
    name : 'a',
    age : 20,
    obj : {id:999},
    action : function(){
        console.log(this.name);
    }
}
let b = JSON.parse(JSON.stringify(a));
a.name = 'b';
a.obj.id = 888;
console.log(a);
console.log(b);

單層對象name和多層對象obj.id的改變都沒影響到原對象,因此是一個比較完美的深拷貝,但是能看到function好像并沒有被拷貝。

可以看出這個方法對于一層和多層都能實現深拷貝,但是這個方法的缺陷是不能拷貝Function,所以在使用時,一定要注意數據類型。

遞歸

let a = {
    name:'a',
    skin:["red","blue","yellow",["123","456"]],
    child:{
        work:'none',
        obj:{
            id:999
        }
    },
    action:function(){
        console.log(this.name);
    }
}
//封裝的遞歸方法
    function copyWid(obj){
        let newObj = Array.isArray(obj)?[]:{};
        for (var i in obj){
            if(typeof obj[i] === 'object'){  //判斷是不是對象(數組或對象)
               newObj[i] = copyWid(obj[i])  //遞歸解決多層拷貝
            }else{
                newObj[i] = obj[i]   
            }
        }
        return newObj;
    };
    let b = copyWid(a);
    b.child.obj.id =888;
    b.skin[3][0] = "pink";
    console.log(a);
    console.log(b);

可以看到,無論是多層的對象還是多層的數組,都能實現深拷貝,而且能拷貝函數,這個是目前來說最完美的深拷貝方法。

通過這個遞歸能實現一個比較完美的深拷貝,能彌補上述提到的所有方法中的缺點。

展開運算符

let a = {name:'a',id:99};//如果是數組[xx,xx,xx],{...a}需要改成[...a]
let b ={...a};  //[...a]
a.id =88;
console.log(a);
console.log(b);

這個方法能實現對象數組單層時的深拷貝,但是多層無法實現深拷貝。

以上這么多方法,最優(yōu)解應該屬于JSON和遞歸的方法(遞歸解決了JSON無法拷貝函數方法的問題),但是根據需求數據類型的不同,可以選擇更簡單的方式。

總結

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關注腳本之家的更多內容! 

相關文章

  • Javascript 網頁黑白效果實現代碼(兼容IE/FF等)

    Javascript 網頁黑白效果實現代碼(兼容IE/FF等)

    今天在網上看到有人推薦的一個不錯的方法,試了一下,效果還是可以的,可以自定義讓網頁的某一部分變成灰度顏色(黑白)。
    2010-04-04
  • 巧用js提交表單輕松解決一個頁面有多個提交按鈕

    巧用js提交表單輕松解決一個頁面有多個提交按鈕

    使用js提交表單想必大家都會,如果要實現一個頁面有多個提交按鈕,你會嗎?下面有個不錯的示例,大家可以感受下
    2013-11-11
  • 深入理解JSON數據源格式

    深入理解JSON數據源格式

    JSON 在很多場合下作為數據格式比XML要更加方便。JSON的數據由對象、數組和元素等格式組成。每種格式都可以包含合法的JavaScript數據類型
    2014-01-01
  • 詳解webpack 多入口配置

    詳解webpack 多入口配置

    本篇文章主要介紹了webpack 多入口配置 ,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06
  • JavaScript獲取當前cpu使用率的方法

    JavaScript獲取當前cpu使用率的方法

    這篇文章主要介紹了JavaScript獲取當前cpu使用率的方法,涉及JavaScript針對系統(tǒng)硬件操作的相關技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-12-12
  • javascript重復綁定事件造成的后果說明

    javascript重復綁定事件造成的后果說明

    最近在修改百度地圖開源的東西,想把里面耦合在一起的代碼給拆分出來。拆解之后,發(fā)現了一些坑爹的問題。邏輯上沒有問題的情況下,該出現的效果沒有出現
    2013-03-03
  • Web前端框架bootstrap實戰(zhàn)【第一次接觸使用】

    Web前端框架bootstrap實戰(zhàn)【第一次接觸使用】

    Bootstrap是Twitter推出的一個開源的前端框架。這篇文章主要介紹了Web前端框架bootstrap實戰(zhàn),需要的朋友可以參考下
    2016-12-12
  • JS實現漂亮的淡藍色滑動門效果代碼

    JS實現漂亮的淡藍色滑動門效果代碼

    這篇文章主要介紹了JS實現漂亮的淡藍色滑動門效果代碼,涉及JavaScript通過自定義函數遍歷頁面元素及動態(tài)設置元素屬性的技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-09-09
  • 快速學習JavaScript的6個思維技巧

    快速學習JavaScript的6個思維技巧

    在這篇文章中,我將介紹六個思維技巧來幫助你更快地學習JavaScript,并成為一個更快樂、更富有成效的程序員。
    2015-10-10
  • layui動態(tài)加載多表頭的實例

    layui動態(tài)加載多表頭的實例

    今天小編就為大家分享一篇layui動態(tài)加載多表頭的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-09-09

最新評論