js物件的深拷貝與淺拷貝詳解
一、淺拷貝
例子:
var Chinese = { nation: '中國', arr: [ 1, 2, 3], obj: { name: 'yzs', age: 18 } }; function extendCopy (p) { var c = {}; for (var i in p) { c[i] = p[i]; } return c; } var Doctor = extendCopy (Chinese); Doctor.arr.push(4); console.log(Doctor); // 其中arr選項變為【1,2,3,4】 console.log(Chinese); // 其中arr選項變為【1,2,3,4】
但是,這樣的拷貝有一個問題。那就是,如果父物件的屬性等於陣列或另一個物件,那麼實際上,子物件獲得的只是一個記憶體地址,而不是真正拷貝,因此存在父物件被篡改的可能。
二、深拷貝
所謂”深拷貝”,就是能夠實現真正意義上的陣列和物件的拷貝。它的實現並不難,只要遞迴呼叫”淺拷貝”就行了。
function deepCopy ( p, c ) { var obj = c||{}; if (p) { for (var i in p) { if (typeof(p[i]) === 'object') { obj[i] = (p[i].constructor === Array ? [] : {}); deepCopy( p[i], obj[i] ); } else { obj[i] = p[i]; } } return obj; } return ''; }
使用深拷貝
console.log('深拷貝');
var Doctor = deepCopy(Chinese);
Doctor.career = '醫生';
Doctor.nation = '美國';
Doctor.arr.push(4);
console.log(Doctor);
console.log(Chinese);
$.extend()
jquery 中$.extend()如同。
$.extend( [deep ], target, object1 [, objectN ] )
•deep
型別: Boolean
如果是true,合併成為遞迴(又叫做深拷貝)。
•target
型別: Object
物件擴充套件。這將接收新的屬性。
•object1
型別: Object
一個物件,它包含額外的屬性合併到第一個引數.
•objectN
型別: Object
包含額外的屬性合併到第一個引數
當我們提供兩個或多個物件給$.extend(),物件的所有屬性都新增到目標物件(target引數)。
如果只有一個引數提供給$.extend(),這意味著目標引數被省略。在這種情況下,jQuery物件本身被預設為目標物件。這樣,我們可以在jQuery的名稱空間下新增新的功能。這對於外掛開發者希望向 jQuery 中新增新函式時是很有用的。
請記住,目標物件(第一個引數)將被修改,並且將通過$.extend()返回。然而,如果我們想保留原物件,我們可以通過傳遞一個空物件作為目標物件:
var object = $.extend({}, object1, object2);
在預設情況下,通過$.extend()合併操作不是遞迴的;如果第一個物件的屬性本身是一個物件或陣列,那麼它將完全用第二個物件相同的key重寫一個屬性。這些值不會被合併。可以通過檢查下面例子中 banana 的值,就可以瞭解這一點。然而,如果將 true 作為該函式的第一個引數,那麼會在物件上進行遞迴的合併。
警告:不支援第一個引數傳遞 false 。
1. 合併兩個物件,並修改第一個物件。
?12345678910111213141516 | var object1 = { apple: 0, banana: { weight: 52, price: 100 }, cherry: 97 }; var object2 = { banana: { price: 200 }, durian: 100 }; // Merge object2 into object1 $.extend( object1, object2 ); // Assuming JSON.stringify - not available in IE<8 console.log( JSON.stringify( object1 ) ); //{"apple":0,"banana":{"price":200},"cherry":97,"durian":100} |
2. 採用遞迴方式合併兩個物件,並修改第一個物件。
?12345678910111213141516 | var object1 = { apple: 0, banana: { weight: 52, price: 100 }, cherry: 97 }; var object2 = { banana: { price: 200 }, durian: 100 }; // Merge object2 into object1, recursively $.extend( true , object1, object2 ); // Assuming JSON.stringify - not available in IE<8 console.log( JSON.stringify( object1 ) ); //{"apple":0,"banana":{"weight":52,"price":200},"cherry":97,"durian":100} |
3. 合併 defaults 和 options 物件,並且不修改 defaults 物件。這是常用的外掛開發模式。
?12345678910111213 | var defaults = { validate: false , limit: 5, name: "foo" }; var options = { validate: true , name: "bar" }; // Merge defaults and options, without modifying defaults var settings = $.extend( {}, defaults, options ); console.log(JSON.stringify( defaults )); console.log(JSON.stringify( options )); console.log(JSON.stringify( settings )); //defaults -- {"validate":false,"limit":5,"name":"foo"} //options -- {"validate":true,"name":"bar"} //settings -- {"validate":true,"limit":5,"name":"bar"} |
相關推薦
js物件的深拷貝與淺拷貝詳解
一、淺拷貝例子:var Chinese = { nation: '中國', arr: [ 1, 2, 3], obj: { name: 'yzs', age: 18 } }; function extendCopy (p) { va
js中的深拷貝與淺拷貝
nbsp 中一 局限性 深拷貝與淺拷貝 ext bsp post body extend 對於字符串類型,淺拷貝是對值的拷貝,對於對象來說,淺拷貝是對對象地址的拷貝,並沒有開辟新的棧,也就是拷貝的結果是兩個對象指向同一個地址,修改其中一個對象的屬性,則另一個對象的屬性也會改
深拷貝與淺拷貝詳解
RoCE 深拷貝 tps sys 實現 java 圖片 public 動態 在講解深拷貝與淺拷貝講解之前,需要先弄懂拷貝的分類:引用拷貝和對象拷貝。 註:深拷貝和淺拷貝都是對象拷貝 1.拷貝的引入 (1)引用拷貝 創建一個指向對象的引用變量的拷貝。 例1
【JS】深拷貝與淺拷貝的區別,實現深拷貝的幾種方法
如何區分深拷貝與淺拷貝,簡單點來說,就是假設B複製了A,當修改A時,看B是否會發生變化,如果B也跟著變了,說明這是淺拷貝,拿人手短,如果B沒變,那就是深拷貝,自食其力。 此篇文章中也會簡單闡述到棧堆,基本資料型別與引用資料型別,因為這些概念能更好的讓你理解深拷貝與淺拷貝。 我們來舉個淺拷貝例
工作日常--js引用型別資料深拷貝與淺拷貝
js資料型別 簡單資料型別 簡單的資料型別包括Undifine,NULL,Bolean,String,Number。這些資料型別的資料的儲存是在堆中儲存的。堆中存放的資料是先進先出。FIFO(first in first out) 引用型別 引用型別包括
淺談js的深拷貝與淺拷貝
今天看es6的時候忽然想到一個問題就是針對於js的深拷貝和淺拷貝的問題,其實說直接點那,就是深複製和淺複製只針對像 Object, Array 這樣的複雜物件的。簡單來說,淺複製只複製一層物件的屬性
Cpp--拷貝建構函式(深拷貝與淺拷貝)詳解
對於普通型別的物件來說,它們之間的複製是很簡單的,例如: int a=88; int b=a; 而類物件與普通物件不同,類物件內部結構一般較為複雜,存在各種成員變數。下面看一個類物件拷貝的簡單例子。 #include <iostream> using name
web前端js基礎之,簡單理解“深拷貝與淺拷貝”
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>簡單理解深拷貝與淺拷貝</title> <
【Java深入】深拷貝與淺拷貝詳解
1.拷貝的引入 (1)引用拷貝 建立一個指向物件的引用變數的拷貝。 例1: Teacher teacher = new Teacher("Taylor",26); Teacher otherteacher = teacher; System.out.
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 一句話總結,淺拷貝只拷貝父對象,不拷貝子對像。 註意:淺拷貝和深拷貝的不同僅僅是對組合對象來說,所謂的組合對象就是包含了其它對象的對象,如列表,類實例。而對於數字、字符串以及其它“原子”類型,沒