淺談js的深拷貝與淺拷貝
今天看es6的時候忽然想到一個問題就是針對於js的深拷貝和淺拷貝的問題,其實說直接點那,就是深複製和淺複製只針對像 Object, Array 這樣的複雜物件的。簡單來說,淺複製只複製一層物件的屬性,而深複製則遞迴複製了所有層級。
因為淺複製只會將物件的各個屬性進行依次複製,並不會進行遞迴複製,而
JavaScript 儲存物件都是存地址的,所以淺複製會導致 obj.arr 和 shadowObj.arr 指向同一塊記憶體地址,大概的示意圖如下。
舉一個列子哈:
let obj = { a:11, b: [22,33] }; function objCopy(src) { let dst= {}; for (let prop in src) { if (src.hasOwnProperty(prop)) { dst[prop] = src[prop]; } } return dst; } let _copy = objCopy(obj);
因為淺複製只會將物件的各個屬性進行依次複製,並不會進行遞迴複製,而 JavaScript 儲存物件都是存地址的,所以淺複製會導致 obj.b和
_copy.b 指向同一塊記憶體地址,大概的示意圖如下。
導致的結果就是這樣:
_copy.arr[1] = 88; obj.b[1] // = 88
而深複製則不同,它不僅將原物件的各個屬性逐個複製出去,而且將原物件各個屬性所包含的物件也依次採用深複製的方法 遞迴複製到新物件上。這就不會存在上面 obj 和 _copy的 b屬性指向同一個物件的問題。
深拷貝要實現的效果是這樣的:
實現深拷貝的方法如下
最簡單的深拷貝,拿好:
b = JSON.parse( JSON.stringify(a) )
不過這有侷限性:
- 無法複製函式
- 原型鏈沒了,物件就是object,所屬的類沒了。
但是簡單,大多時候完全可以滿足需求了
jQuery.extend第一個引數可以是布林值,用來設定是否深度拷貝的:
jQuery.extend(true, { a : { a : "a" } }, { a : { b : "b" } } );
jQuery.extend( { a : { a : "a" } }, { a : { b : "b" } } );
(陣列深拷貝)
var arr = ["One","Two","Three"]; var arrtoo = arr.slice(0); arrtoo[1] = "middle"; document.writeln("陣列的原始值:" + arr + "<br />");//Export:陣列的原始值:One,Two,Three document.writeln("陣列的新值:" + arrtoo + "<br />");//Export:陣列的新值:One,middle,Three
concat() 方法用於連線兩個或多個數組。
該方法不會改變現有的陣列,而僅僅會返回被連線陣列的一個副本。
語法
arrayObject.concat(arrayX,arrayX,......,arrayX)
說明
返回一個新的陣列。該陣列是通過把所有 arrayX 引數新增到 arrayObject 中生成的。如果要進行 concat() 操作的引數是陣列,那麼新增的是陣列中的元素,而不是陣列。
(物件深拷貝)
就是把物件的屬性遍歷一遍,賦給一個新的物件。
var deepCopy= function(source) { var result={};
for (var key in source) {
result[key] = typeof source[key]===’object’? deepCoyp(source[key]): source[key];
}
return result;
}
var cloneObj = function(obj){
var str, newobj = obj.constructor === Array ? [] : {};
if(typeof obj !== 'object'){
return;
} else if(window.JSON){
str = JSON.stringify(obj), //系列化物件
newobj = JSON.parse(str); //還原
} else {
for(var i in obj){
newobj[i] = typeof obj[i] === 'object' ?
cloneObj(obj[i]) : obj[i];
}
}
return newobj;
};
這個函式可以深拷貝 物件和陣列
小弟水平有限,大神勿噴,理解不對的地方請批評指正。謝謝~~
相關推薦
淺談js最基礎的 淺拷貝和 深拷貝
image else typeof 14. img spa == console pre 1.淺拷貝 就是一個對象的 值類型的復制 var dog = { name : ‘小黃‘, // bark : function(){
js 深凍結 與 淺凍結 Object.freeze
1、深凍結 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>js 深凍結 與 淺凍結</title>
淺談JS之setTimeout與setInterval
概念 setTimeout與clearTimeout,以及setInterval與clearInterval均屬於Window物件方法。 方法描述 setTimeout 在指定的毫秒數後呼叫函式或計算表示式。 clearTimeout 取消由 setInterval() 設定的 timeout。取消
淺談js的深拷貝與淺拷貝
今天看es6的時候忽然想到一個問題就是針對於js的深拷貝和淺拷貝的問題,其實說直接點那,就是深複製和淺複製只針對像 Object, Array 這樣的複雜物件的。簡單來說,淺複製只複製一層物件的屬性
js中的深拷貝與淺拷貝
nbsp 中一 局限性 深拷貝與淺拷貝 ext bsp post body extend 對於字符串類型,淺拷貝是對值的拷貝,對於對象來說,淺拷貝是對對象地址的拷貝,並沒有開辟新的棧,也就是拷貝的結果是兩個對象指向同一個地址,修改其中一個對象的屬性,則另一個對象的屬性也會改
【JS】深拷貝與淺拷貝的區別,實現深拷貝的幾種方法
如何區分深拷貝與淺拷貝,簡單點來說,就是假設B複製了A,當修改A時,看B是否會發生變化,如果B也跟著變了,說明這是淺拷貝,拿人手短,如果B沒變,那就是深拷貝,自食其力。 此篇文章中也會簡單闡述到棧堆,基本資料型別與引用資料型別,因為這些概念能更好的讓你理解深拷貝與淺拷貝。 我們來舉個淺拷貝例
工作日常--js引用型別資料深拷貝與淺拷貝
js資料型別 簡單資料型別 簡單的資料型別包括Undifine,NULL,Bolean,String,Number。這些資料型別的資料的儲存是在堆中儲存的。堆中存放的資料是先進先出。FIFO(first in first out) 引用型別 引用型別包括
js物件的深拷貝與淺拷貝詳解
一、淺拷貝例子:var Chinese = { nation: '中國', arr: [ 1, 2, 3], obj: { name: 'yzs', age: 18 } }; function extendCopy (p) { va
web前端js基礎之,簡單理解“深拷貝與淺拷貝”
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>簡單理解深拷貝與淺拷貝</title> <
C#深度學習の----深拷貝與淺拷貝
chan 深度 保存 交流 typeof sta 二進制 object with 本人在進行編程的時候遇到一個問題,要對一個綁定的依賴屬性進行賦值,改變屬性中的某一部分,綁定的目標上的所有值都發生了變化,著並不是我想要的,由此引出深淺拷貝的問題。(請加群交流:4352266
javaScript之深拷貝與淺拷貝
func array efi name 內存空間 數據 xtend 是否 -- js中有兩種數據類型: 1. 基本類型 : Number、String、Boolean、Null、Undefined 2. 復雜類型 : Object 、Ar
c++分文件定義 深拷貝與淺拷貝
淺拷貝1、#include <stdlib.h> #include <iostream> #include "Array.h" using namespace std; int main(void) { Array arr1; arr1.setCount(5); Array
字典的深拷貝與淺拷貝
/usr odin pri 修改 hal sha deepcopy data str 以前只知道用dict2 = dict1 來進行復制(備份),結果發現對dict2做增刪改等操作時,dict1也會隨之變化,反過來也這樣。沒有好好學習基礎的我,自然在這裏面吃了不少的虧。。。
iOS 圖文並茂的帶你了解深拷貝與淺拷貝
mstr ear span ini 5.7 [1] ring void 結束 一、概念與總結 1、淺拷貝 淺拷貝就是對內存地址的復制,讓目標對象指針和源對象指向同一片內存空間,當內存銷毀的時候,指向這片內存的幾個指針需要重新定義才可以使用,要不然會成為野
Python中深拷貝與淺拷貝區別
分配 img 地址 append 淺拷貝 pen image pre 內容 淺拷貝, list值是可變的,str值不可變,只能重新賦值 a=b=c=‘wjx‘print(a,b,c)c= ‘jmy‘#重新賦值了,所以內存分配了新的地址print(a,b,c)print(id
python:深拷貝與淺拷貝
pri 復制 空間 epc python import ams post name import copyname = ["sams", ["su", "ca"]]name0 = name#直接復制,指向同一內存空間name1 = copy.copy(name)#淺拷貝,也
python list的深拷貝與淺拷貝-以及初始化空白list的方法(2)
src 分享圖片 [1] 深拷貝 pen net .com 空白 tails 其實python對於深拷貝與淺拷貝的處理方式依然是很靈活的,甚至有一個專門的工具包copy來做個事情 來看以下這組list的拷貝方法: 已知lista是一個已經定義好了的list listb=l
深拷貝與淺拷貝
post false 所有 console oda 嵌套 lod cti 屬性。 淺拷貝 對於基本類型,淺拷貝是對值的復制,對於對象來說,淺拷貝只復制指向某個對象的指針,而不復制對象本身,並沒有開辟新的棧,也就是復制的結果是新舊對象還是共享同一塊內存,兩個對象指向同一個地址
JavaScript深拷貝與淺拷貝
javascript深拷貝與淺拷貝1.先看一個例子:從中可以看出,obj1拷貝了obj的值,但只是進行了地址的引用,修改obj1的值也影響到了obj的值,沒有創建新對象。 淺拷貝:對基本數據類型進行值傳遞,對引用數據類型進行引用傳遞般的拷貝。 深拷貝:對基本數據類型進行值傳遞,對引用數據類型,創建一個新的對象
python 的深拷貝與淺拷貝
bsp 分享 ima 都是 跟著 class 淺拷貝和深拷貝 分享圖片 src 一句話總結,淺拷貝只拷貝父對象,不拷貝子對像。 註意:淺拷貝和深拷貝的不同僅僅是對組合對象來說,所謂的組合對象就是包含了其它對象的對象,如列表,類實例。而對於數字、字符串以及其它“原子”類型,沒