深拷貝和淺拷貝

一劝术、 基本數(shù)據(jù)類型的拷貝(復(fù)制copy)深拷貝和淺拷貝?

深拷貝和淺拷貝是針對(duì)復(fù)雜數(shù)據(jù)類型來說的崭捍,淺拷貝只拷貝一層噪窘,而深拷貝是層層拷貝

基本數(shù)據(jù)類型? 值傳遞? ??

a = 1.1;b = a;b = 2; console.log(a,b)? ? ? ? ? ? ? ? ? ?Number

a = 'hello';b = a;b = 3; console.log(a,b)? ? ? ? ? ? ? ? ?String

a = false;b = a;b = 'sss'; console.log(a,b)? ? ? ? ? ? ??Boolean??

a = undefined;b = a;b = false; console.log(a,b)? ? ?Undefined? ??

?a = null;b = a;b = undefined; console.log(a,b)? ? ? ? Null

深拷貝

? 深拷貝復(fù)制變量值妆艘,對(duì)于非基本類型的變量植康,則遞歸至基本類型變量后旷太,再?gòu)?fù)制。 深拷貝后的對(duì)象與原來的對(duì)象是完全隔離的销睁,互不影響供璧,對(duì)一個(gè)對(duì)象的修改并不會(huì)影響另一個(gè)對(duì)象。

?淺拷貝

?淺拷貝是會(huì)將對(duì)象的每個(gè)屬性進(jìn)行依次復(fù)制冻记,但是當(dāng)對(duì)象的屬性值是引用類型時(shí)睡毒,實(shí)質(zhì)復(fù)制的是其引用,當(dāng)引用指向的值改變時(shí)也會(huì)跟著變化冗栗。

可以看出淺拷貝只最第一層屬性進(jìn)行了拷貝演顾,當(dāng)?shù)谝粚拥膶傩灾凳腔緮?shù)據(jù)類型時(shí),新的對(duì)象和原對(duì)象互不影響隅居,但是如果第一層的屬性值是復(fù)雜數(shù)據(jù)類型钠至,那么新對(duì)象和原對(duì)象的屬性值其指向的是同一塊內(nèi)存地址。

二胎源、復(fù)雜數(shù)據(jù)類型(object)的拷貝??地址傳遞

常用的復(fù)雜數(shù)據(jù)類型包括:{ }棉钧、[ ]、function(){} 涕蚤、Date(時(shí)間) 宪卿、RegExp 的诵、null(這個(gè)比較特殊)等

?1、我們依然用一的簡(jiǎn)單賦值(=)來進(jìn)行一遍操作(賦值)

? ?經(jīng)過實(shí)踐我們會(huì)發(fā)現(xiàn):

? ? ?1愧捕、當(dāng)類型為{}奢驯、[]的時(shí)候申钩,改變b的值次绘,a也會(huì)跟著一起變化。

? ? ?2撒遣、當(dāng)類型為Date邮偎、function、RegExp的時(shí)候义黎,a保持不變禾进。

? ?總結(jié):我們發(fā)現(xiàn){}或者[]時(shí),簡(jiǎn)單的賦值操作并不能實(shí)現(xiàn)它們的拷貝廉涕,只是改了b的指向泻云,使a和b都指向同一個(gè)引用,隨意改變一個(gè)狐蜕,都會(huì)影響另外一個(gè)的值宠纯。?

? ? // {}

? ? // a = {name: 'abc'};b = a;b.name = 'sss';

? ? // console.log(a,b)

? ? // // []

? ? // a = ['a','b','c'];b = a;b[1] = 'd';

? ? // console.log(a,b)

? ? // // function

? ? // a = function(){ alert('aaa'); };b = a;b = function(){ alert('bbb'); };

? ? // console.log(a.toString(),b.toString())

? ? // // Date

? ? // a = new Date('2018-10-11 00:00:00');b = a;b = new Date('1970-01-01 00:00:00');

? ? // console.log(a,b)

? ? // // RegExp

? ? // a = new RegExp('abc');b = a;b = new RegExp('aaa');

? ? // console.log(a,b)

? ? // 2、Object.assign 和 for in進(jìn)行{}和[]的拷貝(淺拷貝--只能拷貝一層)

? ? // Object.assign

? ? // a = {name: 'aaa'};b = Object.assign({}, a);

? ? // b.name = 'bbb';?

? ? // console.log(a,b)

? ? // a = [1,2,3];b = Object.assign([], a);b[1] = 4;?

? ? // console.log(a,b)

? ? // // for in

? ? // var copy = function(a) {

? ? //? var res = a.constructor();

? ? //? console.log(res)

? ? //? for(var key in a) {

? ? //? if(a.hasOwnProperty(key)) {

? ? //? ? res[key] = a[key];

? ? //? }

? ? //? }

? ? //? return res;

? ? // }

? ? // a = {name: 'aaa'};b = copy(a);b.name = 'bbb';?

? ? // console.log(a,b)

? ? // a = [1,2,3];b = copy(a);b[1] = 4;?

? ? // console.log(a,b)

? // a = {name:'aaa',people:{name: 'abc'}};b = Object.assign({}, a);b.people.name = 'def';

? // console.log(a,b)? ? ? ? ? ? ? ? ? ? ? ?

? // // for in

? //? var copy = function(a) {

? //? ? var res = a.constructor();

? //? ? for(var key in a) {

? //? ? if(a.hasOwnProperty(key)) {

? //? ? ? res[key] = a[key];

? //? ? }

? //? ? }

? //? ? return res;

? //? }

? // a = {name:'aaa',people:{name: 'abc'}};b = copy(a);b.people.name = 'def';

? // console.log(a,b)

? // a = [1,2, {name: 'aaa'}];b = Object.assign([], a);b[2].name = 'bbb';

? // console.log(a,b)

? // a = [1,2, {name: 'aaa'}];b = copy(a);b[2].name = 'bbb';

? // console.log(a,b)

? ? ? ?深拷貝和淺拷貝是針對(duì)復(fù)雜數(shù)據(jù)類型來說的层释,淺拷貝只拷貝一層婆瓜,而深拷貝是層層拷貝。

? 深拷貝

? ? ? 深拷貝復(fù)制變量值贡羔,對(duì)于非基本類型的變量廉白,則遞歸至基本類型變量后,再?gòu)?fù)制乖寒。 深拷貝后的對(duì)象與原來的對(duì)象是完全隔離的猴蹂,互不影響,對(duì)一個(gè)對(duì)象的修改并不會(huì)影響另一個(gè)對(duì)象楣嘁。

? ?淺拷貝

? ? ? ?淺拷貝是會(huì)將對(duì)象的每個(gè)屬性進(jìn)行依次復(fù)制磅轻,但是當(dāng)對(duì)象的屬性值是引用類型時(shí),實(shí)質(zhì)復(fù)制的是其引用马澈,當(dāng)引用指向的值改變時(shí)也會(huì)跟著變化瓢省。 可以使用 for in、 Object.assign痊班、 擴(kuò)展運(yùn)算符 ... 勤婚、Array.prototype.slice()、Array.prototype.concat() 等

// var array = [

? ? //? ? { number: 1 },

? ? //? ? { number: 2 },

? ? //? ? { number: 3 }

? ? // ];

? ? // var copyArray = array.slice();

? ? // copyArray[0].number = 100;

? ? // console.log(array);

? ? // console.log(copyArray);

? ? // let obj = {

? ? //? ? name: 'Yvette',

? ? //? ? age: 18,

? ? //? ? hobbies: ['reading', 'photography']

? ? // }

? ? // let obj2 = Object.assign({}, obj);

? ? // let obj3 = {...obj};

? ? // obj.name = 'Jack';

? ? // obj.hobbies.push('coding');

? ? // console.log(obj);

? ? // console.log(obj2);

? ? // console.log(obj3);

? ? ? ?可以看出淺拷貝只最第一層屬性進(jìn)行了拷貝涤伐,當(dāng)?shù)谝粚拥膶傩灾凳腔緮?shù)據(jù)類型時(shí)馒胆,新的對(duì)象和原對(duì)象互不影響缨称,但是如果第一層的屬性值是復(fù)雜數(shù)據(jù)類型,那么新對(duì)象和原對(duì)象的屬性值其指向的是同一塊內(nèi)存地址祝迂。

? ? ?1.深拷貝最簡(jiǎn)單的實(shí)現(xiàn)是: JSON.parse(JSON.stringify(obj))

? ? JSON.parse(JSON.stringify(obj)) 是最簡(jiǎn)單的實(shí)現(xiàn)方式睦尽,但是有一些缺陷:

? ? ?//對(duì)象的屬性值是函數(shù)時(shí),無(wú)法拷貝型雳。

? ? //? 原型鏈上的屬性無(wú)法拷貝

? ? //? 不能正確的處理 Date 類型的數(shù)據(jù)

? ? //? 不能處理 RegExp

? ? //? 會(huì)忽略 symbol

? ? //? 會(huì)忽略 undefined

遞歸函數(shù)

如果一個(gè)函數(shù)在內(nèi)部調(diào)用自身当凡,這個(gè)函數(shù)就叫做遞歸函數(shù)

遞歸函數(shù):

? ? ? 實(shí)現(xiàn)一個(gè) deepClone 函數(shù) (深拷貝,完美)

? ? ? // 如果是基本數(shù)據(jù)類型纠俭,直接返回

? ? ? // 如果是 RegExp 或者 Date 類型沿量,返回對(duì)應(yīng)類型

? ? ? // 如果是復(fù)雜數(shù)據(jù)類型,遞歸冤荆。

? ? ? // 考慮循環(huán)引用的問題

? ? // var show={

? ? //? ? btn:"btn",

? ? //? ? init:function(){

? ? //? ? ? ? var that=this;

? ? //? ? ? ? alert(this);

? ? //? ? ? ? this.btn.click(function(){

? ? //? ? ? ? ? ? ? ? that.change();

? ? //? ? ? ? ? ? ? ? alert(this);

? ? //? ? ? ? })? ? ? ? ? ?

? ? //? ? },

? ? //? ? change:function(){

? ? //? ? ? ? this.btn.css({'background':'green'});

? ? //? ? ? ? person={

? ? //? ? ? ? ? name:"king",

? ? //? ? ? ? ? show:function(){

? ? //? ? ? ? ? ? console.log(this.name)

? ? //? ? ? ? ? }

? ? //? ? ? ? }

? ? //? ? }

? ? // }



? ? // function deepClone(obj, hash = new WeakMap()) { //遞歸拷貝

? ? //? ? if (obj instanceof RegExp) return new RegExp(obj);

? ? //? ? if (obj instanceof Date) return new Date(obj);

? ? //? ? if (obj === null || typeof obj !== 'object') {

? ? //? ? ? ? //如果不是復(fù)雜數(shù)據(jù)類型朴则,直接返回

? ? //? ? ? ? return obj;

? ? //? ? }

? ? //? ? if (hash.has(obj)) {

? ? //? ? ? ? return hash.get(obj);

? ? //? ? }

? ? ? ? /**

? ? ? ? * 如果obj是數(shù)組,那么 obj.constructor 是 [Function: Array]

? ? ? ? * 如果obj是對(duì)象钓简,那么 obj.constructor 是 [Function: Object]

? ? ? ? */

? ? //? ? let t = new obj.constructor();

? ? //? ? hash.set(obj, t);

? ? //? ? for (let key in obj) {

? ? //? ? ? ? //遞歸

? ? //? ? ? ? if (obj.hasOwnProperty(key)) {//是否是自身的屬性

? ? //? ? ? ? ? ? t[key] = deepClone(obj[key], hash);

? ? //? ? ? ? }

? ? //? ? }

? ? //? ? return t;

? ? // }


? ? // var show2 = cloneObject(show)

? ? // console.log(show2)

//遞歸函數(shù)

// function cloneObject (obj) {

? // var newObj = {}? //如果不是引用類型乌妒,直接返回

? // if (typeof (obj) !== 'object') {

? // ? return obj

? // }

? // //如果是引用類型,遍歷屬性

? // else{

? // for (var attr in obj) {

? // //如果某個(gè)屬性還是引用類型外邓,遞歸調(diào)用

? // ? newObj[attr] = cloneObject(obj[attr])

? // }

? // }

? // return newObj

// }

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末撤蚊,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子坐榆,更是在濱河造成了極大的恐慌拴魄,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,817評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件席镀,死亡現(xiàn)場(chǎng)離奇詭異匹中,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)豪诲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門顶捷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人屎篱,你說我怎么就攤上這事服赎。” “怎么了交播?”我有些...
    開封第一講書人閱讀 157,354評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵重虑,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我秦士,道長(zhǎng)缺厉,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,498評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮提针,結(jié)果婚禮上命爬,老公的妹妹穿的比我還像新娘。我一直安慰自己辐脖,他們只是感情好饲宛,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著嗜价,像睡著了一般艇抠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上炭剪,一...
    開封第一講書人閱讀 49,829評(píng)論 1 290
  • 那天练链,我揣著相機(jī)與錄音翔脱,去河邊找鬼奴拦。 笑死,一個(gè)胖子當(dāng)著我的面吹牛届吁,可吹牛的內(nèi)容都是我干的错妖。 我是一名探鬼主播,決...
    沈念sama閱讀 38,979評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼疚沐,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼暂氯!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起亮蛔,我...
    開封第一講書人閱讀 37,722評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤痴施,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后究流,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體辣吃,經(jīng)...
    沈念sama閱讀 44,189評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評(píng)論 2 327
  • 正文 我和宋清朗相戀三年芬探,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了神得。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,654評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡偷仿,死狀恐怖哩簿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情酝静,我是刑警寧澤节榜,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站别智,受9級(jí)特大地震影響宗苍,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜亿遂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評(píng)論 3 313
  • 文/蒙蒙 一浓若、第九天 我趴在偏房一處隱蔽的房頂上張望渺杉。 院中可真熱鬧,春花似錦挪钓、人聲如沸是越。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)倚评。三九已至,卻和暖如春馏予,著一層夾襖步出監(jiān)牢的瞬間天梧,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工霞丧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留呢岗,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,382評(píng)論 2 360
  • 正文 我出身青樓蛹尝,卻偏偏與公主長(zhǎng)得像后豫,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子突那,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評(píng)論 2 349