js物件淺拷貝與深拷貝

2021-09-24 07:39:33 字數 2932 閱讀 9874

在js中,如果乙個物件,作為變數賦值給另乙個物件,那麼兩個物件得值會是相同得引用位址,其中乙個改變,另外乙個也會隨之改變。

var obj1 = 

var obj2 = obj1;

obj2.num = 456;

console.log(obj1.num); // 輸出: 456

複製**

` 在我們日常開發過程當中,我們去複製乙個物件得目的是為了去獲得該物件的值,我們對獲得的值進行操作,不會影響原物件才對。而我們要解決這樣的問題,就涉及到了使用物件的淺拷貝和深拷貝來解決問題了。

淺拷貝是我們日常開發使用最多的,因為他能解決我們日常開發中絕大部分的問題,首先最常用的方法就是:object.assign(),是es6:object裡的新增方法,object.assign()方法用於物件的合併,將源物件(source)的所有可列舉屬性,複製到目標物件(target),那麼如何使用呢,請看案例:

var obj1 = 

var obj2 = object.assign({}, obj1);

obj2.num = 456;

console.log(obj1.num, obj2.num); // 輸出: 123 456

複製**

使用方法,還是非常簡單的,我們也可以使用擴充套件運算子...的方法來實現淺拷貝: `

var obj1 = 

var obj2 = ;

obj2.num = 456;

console.log(obj1.num, obj2.num); // 輸出: 123 456

複製**

`所謂淺拷貝,實際上指的就是複製物件本身可列舉的屬性,不會拷貝到繼承屬性和可本身可列舉屬性的值也是物件裡的值。

上面那句話的後半段裡看上去有點繞,這裡在講什麼是深拷貝,你就立馬理解了。而這個字我個人覺得就挺通俗易懂了,說白了就是更深層次的拷貝唄。那麼怎麼就是深拷貝呢?看案例: `

var obj1 = 

}var obj2 = object.assign({}, obj1);

obj2.child.str = '子物件的str值';

console.log(obj1.child.str); // 輸出: 子物件的str值

複製**

通過上面的案例,我們發現,我們用了淺拷貝,但是obj1obj2裡面的child子物件還是共用了乙個引用位址,這就是我上面說的那句「本身可列舉屬性裡的值也是物件」,所以我們就需要更深層次的拷貝到這個物件裡來唄,這就需要使用深拷貝了,最常見的深拷貝方法就是:json.parse(json.stringify(obj1)),下面看案例:

var obj1 = 

}var obj2 = json.parse(json.stringify(obj1));

obj2.child.str = '子物件的str值';

console.log(obj1.child.str); // 輸出: 子級物件

複製**

通過使用json.parse(json.stringify(obj1))我們實現了深拷貝,其實該方法的實現原理非常的簡單,json.stringify()是把我們的物件轉換成了json字串,字串屬於基本型別了,已經不存在引用位址了,然後我們在用json,pase()把它轉換回來,此時它已經是乙個新物件了,和原物件沒有任何關係了。通過這樣轉換的方式實現了深拷貝。但是呢,該方法也存在一定的侷限性,或者說是不足:

下面看案例:

let obj = ,

}obj.c = obj.b

obj.e = obj.a

obj.b.c = obj.c

obj.b.d = obj.b

obj.b.e = obj.b.c

let newobj = json.parse(json.stringify(obj))

console.log(newobj)

複製**

如果你的物件像這樣的相互引用賦值的話,那麼你會發現不能使用json.parse(json.stringify(obj1))來實現了,並且還報錯:

不僅如此,在遇到undefined和函式時,也不能正常實現深拷貝:

let obj1 = ,

tel: 13880089009

}let obj2 = json.parse(json.stringify(obj1))

console.log(obj2) //

複製**

這樣只拷貝到了tel乙個屬性值:那麼這個時候就會用到常用得另一種深拷貝方式了:for in

let obj1 = ,

tel: 13880089009

}let obj2 = {}

for (let key in obj1)

console.log(obj2) //

複製**

for in本身是乙個比較耗效能得迴圈方法,它實現得方式也簡單粗暴,就是乙個屬性乙個屬性得賦值,for in還可以遍歷到物件繼承得所有屬性和方法,正是因為這一點,所以for in是個耗效能得主。

本篇章主要講解得是淺拷貝和深拷貝這樣得乙個概念,並給出了個人用得一些淺拷貝和深拷貝得方法,用於對我們日常開發當中注意得一些細節操作。喜歡得朋友給個贊吧,謝謝。

js 物件深拷貝 深拷貝與淺拷貝

前言 最近在複習一些面試的知識點,剛剛好複習到了這一部分,於是就寫下這篇文章記錄一下。一 值型別和引用型別 在學習深拷貝和淺拷貝之前,我們先來了解一下js的變數型別。值型別 vs 引用型別 值型別 值型別主要有 number,string,boolean,symbol,null,undefined ...

JS 物件的深拷貝與淺拷貝

基本型別和引用型別 物件的深拷貝和淺拷貝 基本型別和引用型別 js中包含兩種資料型別,既基本型別和引用型別,基本型別是簡單的資料段,它是按值訪問的,因為基本型別可以操作儲存在變數中的值。而引用型別指的是那些可能由多個值構成的物件。引用型別的值是儲存在記憶體中的物件,在js中,規定不能直接訪問記憶體中...

js深拷貝與淺拷貝

1 基礎知識 基本型別與引用型別 js中可以把變數分成兩部分,基本型別和引用型別。基本型別包括 undefined null boolean number和string 引用型別值可能由多個值構成的物件。在對基礎型別資料進行拷貝時,實際相當於建立新的相同資料 hello 賦值給b var a hel...