淺拷貝和深拷貝

區(qū)別:
1梗掰、數(shù)據(jù)類型是基礎數(shù)據(jù)類型:名字和值都會儲存在棧內(nèi)存中,用淺拷貝不會存在什么問題
2蝠检、引用數(shù)據(jù)類型的數(shù)據(jù),名字存在棧內(nèi)存中挚瘟,值存在堆內(nèi)存中叹谁,但是棧內(nèi)存會提供一個引用的地址指向堆內(nèi)存中的值(對于淺拷貝,這樣是把飲用地址copy給對象存在隱患乘盖。無論是拷貝的對象內(nèi)的數(shù)據(jù)比變化焰檩,還是被拷貝的對象變化,都會引起對方的變化


image.png

image.png

實現(xiàn)淺拷貝的方法:
(1) for···in 循環(huán)遍歷拷貝第一層

function simpleCopy(obj) { 
  var objCopy = Array.isArray(obj) ? [] : {};
  for (const key in obj) {
    objCopy[key] = obj[key];
  }
  return objCopy;
}

(2) object.assign()

var obj = {
    a: 1,
    b: 2
}
var obj1 = Object.assign(obj);
obj1.a = 3;
console.log(obj.a) // 3

(3) 直接賦值

let a=[0,1,2,3,4],
   b=a;
console.log(a===b);
a[0]=1;
console.log(a,b);

實現(xiàn)深拷貝的方法
(1)采用遞歸拷貝所有層級

function deepClone(obj) {
  let objClone = Array.isArray(obj) ? [] : [];
  if (obj && typeof obj === "object") {
    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        //判斷obj子元素是否為對象订框,如果是析苫,遞歸復制
        if (obj[key] && typeof obj[key] === "object") {
          objClone[key] = deepClone(obj[key]);
        }else {
          //如果不是簡單復制
          objClone[key] = obj[key];
        }
      }
    }
  }
  return objClone;
}
let a=[1,2,[3,4],[5,6]],
    b=deepClone(a);
a[0]=2;
console.log(a,b);

(2) 通過JSON對象實現(xiàn)深拷貝

function deepClone(obj) {
  var _obj = JSON.stringify(obj),
  objClone = JSON.parse(_obj);
  return objClone;
}
缺點:無法對對象中的方法實行深拷貝,會顯示undefined

(3) 通過jQuery的extend進行深拷貝

$.extend( [deep ], target, object1 [, objectN ] )

(4) lodash 插件參拷貝

// 導入lodash
import _ from 'lodash'
// loodash.cloneDeep(obj)深拷貝
const form = _.cloneDeep(this.addForm)
form.goods_cat = form.goods_cat.join(',')

(5) 如果對象的value是基本數(shù)據(jù)類型 可以用Object.assign(),但是要把它賦值給一個空對象

var obj = {
    a: 1,
    b: 2
}
var obj1 = Object.assign({}, obj); // obj賦值給一個空{(diào)}
obj1.a = 3;
console.log(obj.a);// 1

(6)slice實現(xiàn)對數(shù)組的拷貝

// 當數(shù)組里面的值是基本數(shù)據(jù)類型衩侥,比如String浪腐,Number,Boolean時顿乒,屬于深拷貝
// 當數(shù)組里面的值是引用數(shù)據(jù)類型议街,比如Object,Array時璧榄,屬于淺拷貝
var arr1 = ["1","2","3"]; 
var arr2 = arr1.slice(0);
arr2[1] = "9";
console.log("數(shù)組的原始值:" + arr1 );
console.log("數(shù)組的新值:" + arr2 );

(7) concat 實現(xiàn)對數(shù)組的深拷貝

// 當數(shù)組里面的值是基本數(shù)據(jù)類型特漩,比如String,Number骨杂,Boolean時涂身,屬于深拷貝
var arr1 = ["1","2","3"];
var arr2 = arr1.concat();
arr2[1] = "9";
console.log("數(shù)組的原始值:" + arr1 );
console.log("數(shù)組的新值:" + arr2 );
// 當數(shù)組里面的值是引用數(shù)據(jù)類型,比如Object搓蚪,Array時蛤售,屬于淺拷貝
var arr1 = [{a:1},{b:2},{c:3}];
var arr2 = arr1.concat();
arr2[0].a = "9";
console.log("數(shù)組的原始值:" + arr1[0].a ); // 數(shù)組的原始值:9
console.log("數(shù)組的新值:" + arr2[0].a ); // 數(shù)組的新值:9

(8)直接使用var newObj = Object.create(oldObj),可以達到深拷貝的效果妒潭。

function deepClone(initalObj, finalObj) {    
  var obj = finalObj || {};    
  for (var i in initalObj) {        
    var prop = initalObj[i];        // 避免相互引用對象導致死循環(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;
}

(9) 擴展符實現(xiàn)拷貝

// 當value是基本數(shù)據(jù)類型,比如String雳灾,Number漠酿,Boolean時,是可以使用拓展運算符進行深拷貝的
// 當value是引用類型的值谎亩,比如Object炒嘲,Array,引用類型進行深拷貝也只是拷貝了引用地址匈庭,所以屬于淺拷貝
var car = {brand: "BMW", price: "380000", length: "5米"}
var car1 = { ...car, price: "500000" }
console.log(car1); // { brand: "BMW", price: "500000", length: "5米" }
console.log(car); // { brand: "BMW", price: "380000", length: "5米" }

(10) 手動賦值實現(xiàn)深拷貝(實際開發(fā)過程中不常用)

let obj1 = {
 a: 1,
 b: 2
}
let obj2 = {
 a: obj1.a,
 b: obj1.b
}
obj2.a = 3;
alert(obj1.a); // 1
alert(obj2.a); // 3

---該文章內(nèi)容來自 http://www.reibang.com/p/1c142ec2ca45 主要用于方便個人查閱

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末夫凸,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子阱持,更是在濱河造成了極大的恐慌夭拌,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件紊选,死亡現(xiàn)場離奇詭異啼止,居然都是意外死亡道逗,警方通過查閱死者的電腦和手機兵罢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來滓窍,“玉大人卖词,你說我怎么就攤上這事。” “怎么了此蜈?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵即横,是天一觀的道長。 經(jīng)常有香客問我裆赵,道長东囚,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任战授,我火速辦了婚禮页藻,結果婚禮上,老公的妹妹穿的比我還像新娘植兰。我一直安慰自己份帐,他們只是感情好,可當我...
    茶點故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布楣导。 她就那樣靜靜地躺著废境,像睡著了一般。 火紅的嫁衣襯著肌膚如雪筒繁。 梳的紋絲不亂的頭發(fā)上噩凹,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天,我揣著相機與錄音毡咏,去河邊找鬼栓始。 笑死,一個胖子當著我的面吹牛血当,可吹牛的內(nèi)容都是我干的幻赚。 我是一名探鬼主播,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼臊旭,長吁一口氣:“原來是場噩夢啊……” “哼落恼!你這毒婦竟也來了?” 一聲冷哼從身側響起离熏,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤佳谦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后滋戳,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體钻蔑,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年奸鸯,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片窗怒。...
    茶點故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡辜昵,死狀恐怖堪置,靈堂內(nèi)的尸體忽然破棺而出优构,到底是詐尸還是另有隱情雁竞,我是刑警寧澤碑诉,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布德挣,位于F島的核電站格嗅,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏贴铜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一间坐、第九天 我趴在偏房一處隱蔽的房頂上張望劳澄。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至瓦宜,卻和暖如春蔚万,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背临庇。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工反璃, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人假夺。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓版扩,卻偏偏與公主長得像,于是被迫代替她去往敵國和親侄泽。 傳聞我的和親對象是個殘疾皇子礁芦,可洞房花燭夜當晚...
    茶點故事閱讀 45,092評論 2 355

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