js對(duì)象淺拷貝和深拷貝詳解
本文為大家分享了JavaScript對(duì)象的淺拷貝和深拷貝代碼,供大家參考,具體內(nèi)容如下
1.淺拷貝
拷貝就是把父對(duì)像的屬性,全部拷貝給子對(duì)象。
下面這個(gè)函數(shù),就是在做拷貝:
var Chinese = { nation:'中國(guó)' } var Doctor = { career:'醫(yī)生' } function extendCopy(p) { var c = {}; for (var i in p) { c[i] = p[i]; } c.uber = p; return c; }
使用的時(shí)候,這樣寫:
var Doctor = extendCopy(Chinese); Doctor.career = '醫(yī)生'; alert(Doctor.nation); // 中國(guó)
但是,這樣的拷貝有一個(gè)問(wèn)題。那就是,如果父對(duì)象的屬性等于數(shù)組或另一個(gè)對(duì)象,那么實(shí)際上,子對(duì)象獲得的只是一個(gè)內(nèi)存地址,而不是真正拷貝,因此存在父對(duì)象被篡改的可能。
請(qǐng)看,現(xiàn)在給Chinese添加一個(gè)”出生地”屬性,它的值是一個(gè)數(shù)組。
Chinese.birthPlaces = ['北京','上海','香港'];
通過(guò)extendCopy()函數(shù),Doctor繼承了Chinese。
var Doctor = extendCopy(Chinese);
然后,我們?yōu)镈octor的”出生地”添加一個(gè)城市:
Doctor.birthPlaces.push('廈門');
看一下輸入結(jié)果
alert(Doctor.birthPlaces); //北京, 上海, 香港, 廈門
alert(Chinese.birthPlaces); //北京, 上海, 香港, 廈門
結(jié)果是兩個(gè)的出生地都被改了。
所以,extendCopy() 只是拷貝了基本類型的數(shù)據(jù),我們把這種拷貝叫做“淺拷貝”。
2.深拷貝
因?yàn)闇\深拷有如此弊端所以我們接下來(lái)看一下深拷貝
所謂”深拷貝”,就是能夠?qū)崿F(xiàn)真正意義上的數(shù)組和對(duì)象的拷貝。它的實(shí)現(xiàn)并不難,只要遞歸調(diào)用”淺拷貝”就行了。
function deepCopy(p, c) { var c = c || {}; for (var i in p) { if (typeof p[i] === 'object') { c[i] = (p[i].constructor === Array) ? [] : {}; deepCopy(p[i], c[i]); } else { c[i] = p[i]; } } return c; }
看一下使用方法:
var Doctor = deepCopy(Chinese);
現(xiàn)在,給父對(duì)象加一個(gè)屬性,值為數(shù)組。然后,在子對(duì)象上修改這個(gè)屬性:
Chinese.birthPlaces = ['北京','上海','香港']; Doctor.birthPlaces.push('廈門'); alert(Doctor.birthPlaces); //北京, 上海, 香港, 廈門 alert(Chinese.birthPlaces); //北京, 上海, 香港
這樣就完成了拷貝;
$.extend()
jquery 中$.extend()如同。
$.extend( [deep ], target, object1 [, objectN ] )
•deep
類型: Boolean
如果是true,合并成為遞歸(又叫做深拷貝)。
•target
類型: Object
對(duì)象擴(kuò)展。這將接收新的屬性。
•object1
類型: Object
一個(gè)對(duì)象,它包含額外的屬性合并到第一個(gè)參數(shù).
•objectN
類型: Object
包含額外的屬性合并到第一個(gè)參數(shù)
當(dāng)我們提供兩個(gè)或多個(gè)對(duì)象給$.extend(),對(duì)象的所有屬性都添加到目標(biāo)對(duì)象(target參數(shù))。
如果只有一個(gè)參數(shù)提供給$.extend(),這意味著目標(biāo)參數(shù)被省略。在這種情況下,jQuery對(duì)象本身被默認(rèn)為目標(biāo)對(duì)象。這樣,我們可以在jQuery的命名空間下添加新的功能。這對(duì)于插件開(kāi)發(fā)者希望向 jQuery 中添加新函數(shù)時(shí)是很有用的。
請(qǐng)記住,目標(biāo)對(duì)象(第一個(gè)參數(shù))將被修改,并且將通過(guò)$.extend()返回。然而,如果我們想保留原對(duì)象,我們可以通過(guò)傳遞一個(gè)空對(duì)象作為目標(biāo)對(duì)象:
var object = $.extend({}, object1, object2);
在默認(rèn)情況下,通過(guò)$.extend()合并操作不是遞歸的;如果第一個(gè)對(duì)象的屬性本身是一個(gè)對(duì)象或數(shù)組,那么它將完全用第二個(gè)對(duì)象相同的key重寫一個(gè)屬性。這些值不會(huì)被合并??梢酝ㄟ^(guò)檢查下面例子中 banana 的值,就可以了解這一點(diǎn)。然而,如果將 true 作為該函數(shù)的第一個(gè)參數(shù),那么會(huì)在對(duì)象上進(jìn)行遞歸的合并。
警告:不支持第一個(gè)參數(shù)傳遞 false 。
1. 合并兩個(gè)對(duì)象,并修改第一個(gè)對(duì)象。
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. 采用遞歸方式合并兩個(gè)對(duì)象,并修改第一個(gè)對(duì)象。
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 對(duì)象,并且不修改 defaults 對(duì)象。這是常用的插件開(kāi)發(fā)模式。
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"}
Javascript 判斷對(duì)象是否相等
在Javascript中相等運(yùn)算包括”==”,”===”全等,兩者不同之處,不必多數(shù),本篇文章我們將來(lái)講述如何判斷兩個(gè)對(duì)象是否相等? 你可能會(huì)認(rèn)為,如果兩個(gè)對(duì)象有相同的屬性,以及它們的屬性有相同的值,那么這兩個(gè)對(duì)象就相等。那么下面我們通過(guò)一個(gè)實(shí)例來(lái)論證下:
var obj1 = { name: "Benjamin", sex : "male" } var obj2 = { name: "Benjamin", sex : "male" } //Outputs: false console.log(obj1 == obj2); //Outputs: false console.log(obj1 === obj2);
通過(guò)上面的例子可以看到,無(wú)論使用”==”還是”===”,都返回false。主要原因是基本類型string,number通過(guò)值來(lái)比較,而對(duì)象(Date,Array)及普通對(duì)象通過(guò)指針指向的內(nèi)存中的地址來(lái)做比較。看下面一個(gè)例子:
var obj1 = { name: "Benjamin", sex : "male" }; var obj2 = { name: "Benjamin", sex : "male" }; var obj3 = obj1; //Outputs: true console.log(obj1 == obj3); //Outputs: true console.log(obj1 === obj3); //Outputs: false console.log(obj2 == obj3); //Outputs: false console.log(obj2 === obj3);
上例返回true,是因?yàn)閛bj1和ob3的指針指向了內(nèi)存中的同一個(gè)地址。和面向?qū)ο蟮恼Z(yǔ)言(Java/C++)中值傳遞和引用傳遞的概念相似。 因?yàn)?,如果你想判斷兩個(gè)對(duì)象是否相等,你必須清晰,你是想判斷兩個(gè)對(duì)象的屬性是否相同,還是屬性對(duì)應(yīng)的值是否相同,還是怎樣?
function person(name) { this.name=name; } var p1 = new person("p1"); var p2 = new person("p2"); console.log(p1 == p2); //false person.prototype.sayHi = function() { // do sayHi here } console.log(p1.sayHi() == p2.sayHi()); //true console.log(p1.sayHi() === p2.sayHi()); //true
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
JavaScript 十六進(jìn)制RGB色碼轉(zhuǎn)換器
JavaScript 十六進(jìn)制RGB色碼轉(zhuǎn)換器,大家可以學(xué)習(xí)下思路。2009-08-08three.js中正交與透視投影相機(jī)的實(shí)戰(zhàn)應(yīng)用指南
在three.js中攝像機(jī)的作用就是不斷的拍攝我們創(chuàng)建好的場(chǎng)景,然后通過(guò)渲染器渲染到屏幕中,下面這篇文章主要給大家介紹了關(guān)于three.js中正交與透視投影相機(jī)應(yīng)用的相關(guān)資料,需要的朋友可以參考下2022-08-08js實(shí)現(xiàn)同一頁(yè)面多個(gè)運(yùn)動(dòng)效果的方法
這篇文章主要介紹了js實(shí)現(xiàn)同一頁(yè)面多個(gè)運(yùn)動(dòng)效果的方法,涉及javascript操作頁(yè)面元素運(yùn)動(dòng)效果的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04Typescript中的數(shù)據(jù)類型實(shí)例總結(jié)
ts中數(shù)據(jù)類型的定義是重點(diǎn)之一,所以必須明確ts有哪些數(shù)據(jù)類型,下面這篇文章主要給大家介紹了關(guān)于Typescript中數(shù)據(jù)類型的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-03-03bootstrap datetimepicker2.3.11時(shí)間插件使用
這篇文章主要為大家詳細(xì)介紹了bootstrap datetimepicker2.3.11時(shí)間插件使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11JavaScript中常用的字符串方法函數(shù)操作方法總結(jié)
這篇文章主要介紹了JavaScript中所有的字符串函數(shù)操作方法整理匯總,包括字符串的長(zhǎng)度、連接、查找、截取、替換、分隔、轉(zhuǎn)換等處理方法,以及網(wǎng)址中獲取文件名等等,需要的朋友可以參考下2023-12-12JavaScript省市級(jí)聯(lián)下拉菜單實(shí)例
這篇文章主要為大家詳細(xì)介紹了JavaScript省市級(jí)聯(lián)下拉菜單實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02JavaScript實(shí)現(xiàn)限時(shí)秒殺功能
各種電商活動(dòng)都喜換選擇限時(shí)秒殺活動(dòng)形式,這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)限時(shí)秒殺功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08