:拷貝這個詞顧名思義 就是複製 但是在程式中複製卻有很大差距,資料型別有基本資料型別和引用資料型別 。基本資料的拷貝就是拷貝的值,而引用資料型別複製的值其實複製的是位址,正是因為這樣所以我們一般都是建立乙個新的空物件 然後遍歷舊物件。但是如果舊物件的屬性是引用資料型別的話,遍歷時其實拷貝的是位址。就要在遞迴呼叫,也就是所謂的深拷貝,本篇文章不介紹了,可以去我其他文章**。
var obj=
function
clone
(obj)
for(
var key in obj)
}return newobj
}var obj2=
clone
(obj)
console.
log(obj,obj2)
console.
log(obj==obj2)
結果如下圖
object.assign(target,source) 方法可以把任意多個的源物件自身的可列舉物件屬性拷貝給目標物件然後返回目標物件 但需要注意的是object.assign() 進行的到底是深拷貝還是淺拷貝呢 object.assign()其實 是淺拷貝 不能算深拷貝
var obj=
, hobbies:
["籃球"
,"足球"]}
var newobj=object.
assign
(,obj)
newobj.hobbies.
pop(
) newobj.skill=
console.
log(newobj,obj)
遍歷時newobj.hobbies 其實和obj.hobbies 拷貝的是位址 兩者指向的是同乙個物件 newobj.skill={} 為什麼這邊兩個不一樣呢 因為newobj.skill指向了乙個物件 位址發生改變了,但是之前的還是沒有發生變化。
看變化
var obj=
, hobbies:
["籃球"
,"足球"]}
var newobj=object.
assign
(,obj)
newobj.skill.read=
"news"
newobj.skill.play=
["lol"
]// 你會發現原來的物件裡的屬性read 被改變了
concat() 是陣列裡的乙個內建方法,用來合併兩個陣列或者多個陣列,其實他還具有打散陣列的功能。這裡我們不深究,主要 討論的是淺拷貝乙個
陣列。 這個方法返回乙個新陣列,而不是修改原陣列。
你會想不應該互不干擾? 但是在拷貝的時候 拷貝newarr[4]的位址 所以兩者指的還是同乙個物件。
var arr=[1
,2,3
,4,]
var newarr=array.prototype.
concat([
],arr)
newarr[4]
.name=
"hh"
console.
log(newarr,arr)
結果如下圖
你會發現新舊陣列都發生改變了,因為兩個陣列物件的位址不一樣互不干擾。 看下面例子。
slice() 也是陣列中的乙個內建方法,該方法會返回乙個新物件。slice() 不會改變原陣列
var arr=[[
1,2]
,3,4
,]var newarr=arr.
slice()
newarr[0]
=[1,
2,3]
console.
log(newarr,arr)
這裡newarr[0]拷貝的時候 位址是一樣的指向同乙個物件,但是新陣列→了新的物件兩者還是互不干擾的。
改變二級屬性時,發現又不同了
他和前面的concat()表現得淺拷貝一摸一樣。
JS 物件陣列淺拷貝,深拷貝
物件陣列的深拷貝與淺拷貝,簡單點來說,就是b複製了a,當a被修改時,未操作b,但b也跟著變了,就是淺拷貝,反之是深拷貝 深拷貝本身只針對較為複雜的object型別資料 淺拷貝 var a var b a a 1 age 18 console.log a,b 執行結果,a,b的age都發生了改變 偽深...
js 中陣列或者物件的深拷貝和淺拷貝
淺拷貝 就是兩個js 物件指向同一塊記憶體位址,所以當obj1 obj2指向obj3的時候,一旦其中乙個改變,其他的便會改變!深拷貝 就是重新複製一塊記憶體,這樣就不會互相影響。有些時候我們定義乙個陣列,把這個資料賦值給跟多物件陣列中的乙個字段,當我們改變物件陣列中的該字段的時候,我們會把原來的陣列...
JS中實現陣列和物件的深拷貝和淺拷貝
陣列的深拷貝,兩層 var arr 1,2,3 4,5,6 7,8,9 var arr2 迴圈第一層陣列 for var i 0,len arr.length i console.log arr2 1,2,3,4,5,6,7,8,9 console.log arr arr2 false 陣列的淺拷貝...