Js的深淺拷貝

轉(zhuǎn)載于:https://www.cnblogs.com/136asdxxl/p/8645750.html

一、js 數(shù)據(jù)類型

javaScritp的數(shù)據(jù)類型有:數(shù)值類型黍图、字符串類型厨喂、布爾類型和措、null、undefined杯聚、對象(數(shù)組臼婆、正則表達式、日期幌绍、函數(shù))颁褂,大致分成兩種:基本數(shù)據(jù)類型和引用數(shù)據(jù)類型,
其中:
(1)基本數(shù)據(jù)類型:數(shù)值傀广、字符串颁独、布爾、null伪冰、undefined (值類型
(2)復(fù)雜(復(fù)合)數(shù)據(jù)類型:對象 (引用類型)

基本數(shù)據(jù)類型保存在棧內(nèi)存誓酒,引用類型保存在堆內(nèi)存中。根本原因在于保存在棧內(nèi)存的必須是大小固定的數(shù)據(jù),引用類型的大小不固定靠柑,只能保存在堆內(nèi)存中寨辩,但是可以把它的地址寫在棧內(nèi)存中以供我們訪問。

如果是基本數(shù)據(jù)類型歼冰,則按值訪問靡狞,操作的就是變量保存的值;如果是引用類型的值隔嫡,我們只是通過保存在變量中的引用類型的地址來操作實際對象甸怕。

var a = 1;//定義了一個number類型
var obj1 = {//定義了一個object類型
    name:'obj'
};
基本數(shù)據(jù)類型

1、基本類型的復(fù)制

var a = 1;
var b = a;//復(fù)制
console.log(b)//1
a = 2;//改變a的值
console.log(b)//1

賦值的時候腮恩,在棧內(nèi)存中重新開辟內(nèi)存梢杭,存放變量b,所以在棧內(nèi)存中分別存放著變量a秸滴、b各自的值武契,修改時互不影響。


2缸榛、引用類型的復(fù)制

var color1 = ['red','green'];
var color2 = color1;//復(fù)制
console.log(color2)//['red','green'];
color1.push('black') ;//改變color1的值
console.log(color2)//['red','green','black']

color1與color2指向堆內(nèi)存中同一地址的同一對象吝羞,復(fù)制的只是引用地址。


引用類型

二内颗、深淺拷貝 :

淺拷貝只復(fù)制指向某個對象的指針钧排,而不復(fù)制對象本身,新舊對象還是共享同一塊內(nèi)存均澳。但深拷貝會另外創(chuàng)造一個一模一樣的對象恨溜,新對象跟原對象不共享內(nèi)存,修改新對象不會改到原對象找前。

1糟袁、淺拷貝
淺拷貝只是拷貝基本類型的數(shù)據(jù),如果父對象的屬性等于數(shù)組或另一個對象躺盛,那么實際上项戴,子對象獲得的只是一個內(nèi)存地址,因此存在父對象被篡改的可能槽惫,淺拷貝只復(fù)制指向某個對象的指針周叮,而不復(fù)制對象本身,新舊對象還是共享同一塊內(nèi)存界斜。

var Nation = {  
            nation: '中國'
        };function extendCopy(p) {  
            var c = {};  
            for (var i in p) {    
                c[i] = p[i];  
            }  
            return c;
        }
        var Doctor = extendCopy(Nation);
        Doctor.career = '醫(yī)生';
        Doctor.nation = '美國';
        console.log(Doctor.nation); // 美國
        console.log(Nation.nation); // 中國
        console.log(Doctor.career); // 醫(yī)生
        console.log(Doctor.__proto_ === Nation.__proto_) // true
     // 這里涉及到使用拷貝父對象的屬性實現(xiàn)繼承
var obj = {
          a: "hello",
          b:{
              a: "world",
              b: 21
            },
          c:["Bob", "Tom", "Jenny"],
          d:function() {
              alert("hello world");
            }
        }
       
        var obj1 = simpleClone(obj);
        console.log('obj1=>>>',obj1);
        // 1仿耽、
        obj1.c = ['mm', "Tom", "Jenny"]; // 一層,作為整體各薇,重寫项贺,全改變;改變屬性值,不改變原對象
        console.log('obj=>>>',obj); //obj.c => ["Bob", "Tom", "Jenny"]
     // 2开缎、
       obj1.c[0] = 'mm'; // 淺拷貝時棕叫,改變屬性的屬性值,改變原對象
        console.log('obj=>>>',obj); //obj.c => ["mm", "Tom", "Jenny"]



淺拷貝函數(shù):

function simpleClone(initalObj) {    
          var obj = {};    
          for ( var i in initalObj) {
            obj[i] = initalObj[i];
          }    
          return obj;
        }



2啥箭、深拷貝

深拷貝就是能夠?qū)崿F(xiàn)真正意義上的數(shù)組和對象的拷貝谍珊。遞歸調(diào)用"淺拷貝"。(深拷貝會另外創(chuàng)造一個一模一樣的對象急侥,新對象跟原對象不共享內(nèi)存,修改新對象不會改到原對象)

深拷貝函數(shù):

寫法一:
        function deepClone(initalObj, finalObj) {
            var obj = finalObj || {};
            for (var i in initalObj) {
                var prop = initalObj[i];
          
                // 避免相互引用對象導(dǎo)致死循環(huán)侮邀,如initalObj.a = initalObj的情況
                if(prop === obj) {
                    continue;
                }
          
                if (typeof prop === 'object') {
                    obj[i] = (prop.constructor === Array) ? [] : {};
                    arguments.callee(prop, obj[i]);
                } else {
                    obj[i] = prop;
                }
            }
            return obj;
        }

寫法二:
        function deepClone(initalObj, finalObj) {
            var obj = finalObj || {};
            for (var i in initalObj) {
                var prop = initalObj[i];
          
                // 避免相互引用對象導(dǎo)致死循環(huán)坏怪,如initalObj.a = initalObj的情況
                if(prop === obj) {
                    continue;
                }
          
                if (typeof prop === 'object') {
                    obj[i] = (prop.constructor === Array) ? [] : Object.create(prop);
                } else {
                    obj[i] = prop;
                }
            }
            return obj;
        }
寫法三:

        也可以通過利用 JSON 對象中的 parse 和 stringify 方法,將一個對象轉(zhuǎn)換為字符串绊茧,賦給新的對象控妻,再轉(zhuǎn)回JSON對象装获。


三、深拷貝的應(yīng)用實例

// jquery 有提供一個$.extend可以用來做 Deep Copy。
        var $ = require('jquery');
        var obj1 = {
            a: 1,
            b: { f: { g: 1 } },
            c: [1, 2, 3]
        };
        var obj2 = $.extend(true, {}, obj1);
        console.log(obj1.b.f === obj2.b.f);
        // false
        
        // 函數(shù)庫lodash覆旭,有提供_.cloneDeep用來做 Deep Copy。
        var _ = require('lodash');
        var obj1 = {
            a: 1,
            b: { f: { g: 1 } },
            c: [1, 2, 3]
        };
        var obj2 = _.cloneDeep(obj1);
        console.log(obj1.b.f === obj2.b.f);
        // false



加油哦脸狸!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末祠乃,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子仑乌,更是在濱河造成了極大的恐慌百拓,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件晰甚,死亡現(xiàn)場離奇詭異衙传,居然都是意外死亡,警方通過查閱死者的電腦和手機厕九,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門蓖捶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人扁远,你說我怎么就攤上這事俊鱼。” “怎么了穿香?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵亭引,是天一觀的道長。 經(jīng)常有香客問我皮获,道長焙蚓,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮购公,結(jié)果婚禮上萌京,老公的妹妹穿的比我還像新娘。我一直安慰自己宏浩,他們只是感情好知残,可當(dāng)我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著比庄,像睡著了一般求妹。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上佳窑,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天制恍,我揣著相機與錄音,去河邊找鬼神凑。 笑死净神,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的溉委。 我是一名探鬼主播鹃唯,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼瓣喊!你這毒婦竟也來了坡慌?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤型宝,失蹤者是張志新(化名)和其女友劉穎八匠,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體趴酣,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡梨树,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了岖寞。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抡四。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖仗谆,靈堂內(nèi)的尸體忽然破棺而出指巡,到底是詐尸還是另有隱情,我是刑警寧澤隶垮,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布藻雪,位于F島的核電站,受9級特大地震影響狸吞,放射性物質(zhì)發(fā)生泄漏勉耀。R本人自食惡果不足惜指煎,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望便斥。 院中可真熱鬧至壤,春花似錦、人聲如沸枢纠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽晋渺。三九已至镰绎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間些举,已是汗流浹背跟狱。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留户魏,地道東北人。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓挪挤,卻偏偏與公主長得像叼丑,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子扛门,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內(nèi)容

  • JS關(guān)于基礎(chǔ)類型和引用類型的數(shù)據(jù)請點擊:JS數(shù)據(jù)類型請充分理解之后再來看這篇文章哦~ 基本類型的拷貝 先來看一段非...
    李博洋li閱讀 875評論 0 1
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,092評論 1 32
  • js的深淺拷貝可以分為數(shù)組的深淺拷貝和對象的深淺拷貝 一鸠信、數(shù)組的深淺拷貝如果只是簡單的將數(shù)組中的元素付給另外一個數(shù)...
    碼老二閱讀 538評論 0 1
  • 1.設(shè)計模式是什么星立? 你知道哪些設(shè)計模式,并簡要敘述葬凳?設(shè)計模式是一種編碼經(jīng)驗绰垂,就是用比較成熟的邏輯去處理某一種類型...
    龍飝閱讀 2,140評論 0 12
  • 內(nèi)存管理 簡述OC中內(nèi)存管理機制。與retain配對使用的方法是dealloc還是release火焰,為什么劲装?需要與a...
    丶逐漸閱讀 1,950評論 1 16