JavaScript對象的淺拷貝與深拷貝實例分析
本文實例講述了JavaScript對象的淺拷貝和深拷貝。分享給大家供大家參考,具體如下:
1、淺拷貝
僅僅復(fù)制對象的引用,而不是對象本身。
var person = { name: 'Alice', friends: ['Bruce', 'Cindy'] } var student = { id: 30 } student = simpleClone(person, student); student.friends.push('David'); alert(person.friends); function simpleClone(oldObj, newObj) { var newObj = newObj || {}; for (var i in oldObj) newObj[i] = oldObj[i]; return newObj; }
使用在線HTML/CSS/JavaScript代碼運行工具:http://tools.jb51.net/code/HtmlJsRun,測試運行結(jié)果:
給子對象的數(shù)組類型的屬性添加一個新值,父對象的該屬性值也被篡改。
2、深拷貝
把復(fù)制的對象所引用的全部對象都復(fù)制一遍,能夠?qū)崿F(xiàn)真正意義上的數(shù)組和對象的拷貝。
淺拷貝的問題:如果父對象的屬性值為一個數(shù)組或另一個對象,那么實際上子對象獲得的只是一個內(nèi)存地址,而不是對父對象的真正拷貝,因此存在父對象被篡改的可能。
解決方法:使用深拷貝。
var person = { name: 'Alice', friends: ['Bruce', 'Cindy'] } var student = { id: 30 } student = deepClone(person, student); student.friends.push('David'); alert(person.friends); // 'Bruce', 'Cindy' function deepClone(oldObj, newObj) { var newObj = newObj || {}; newObj = JSON.parse(JSON.stringify(oldObj)); return newObj; }
使用在線HTML/CSS/JavaScript代碼運行工具:http://tools.jb51.net/code/HtmlJsRun,測試運行結(jié)果:
3、實現(xiàn)深拷貝的方法
1) 方法1:使用JSON.parse()方法
function deepClone(oldObj, newObj) { var newObj = newObj || {}; newObj = JSON.parse(JSON.stringify(oldObj)); return newObj; }
優(yōu)點:
簡單易用。
缺點:
① 會拋棄對象的constructor,即,深拷貝后,不管該對象原來的構(gòu)造函數(shù)是什么,在深拷貝之后都會變成Object。
② 能正確處理的對象只有 Number, String, Boolean, Array,即那些能夠被JSON直接表示的數(shù)據(jù)結(jié)構(gòu),RegExp對象等無法通過這種方式深拷貝。
2) 方法2:遞歸拷貝
function deepClone(oldObj, newObj) { var newObj = newObj || {}; for (var i in oldObj) { if (typeof oldObj[i] === 'object') { newObj[i] = (oldObj[i].constructor === Array) ? [] : {}; arguments.callee(oldObj[i], newObj[i]); } else newObj[i] = oldObj[i]; } return newObj; }
問題:當(dāng)遇到兩個互相引用的對象,會出現(xiàn)死循環(huán)的情況。
解決方法:在遍歷時判斷兩個對象是否相互引用(如oldObj.property === newObj),如果是則退出循環(huán)。
function deepClone(oldObj, newObj) { var newObj = newObj || {}; for (var i in oldObj) { var prop = oldObj[i]; if (prop === newObj) continue; if (typeof prop === 'object') { newObj[i] = (prop.constructor === Array) ? [] : {}; arguments.callee(prop, newObj[i]); } else newObj[i] = prop; } return newObj; }
3) 方法3:使用Object.create()
方法
function deepClone(oldObj, newObj) { var newObj = newObj || {}; for (var i in oldObj) { var prop = oldObj[i]; if (prop === newObj) continue; if (typeof prop === 'object') newObj[i] = (prop.constructor === Array) ? [] : Object.create(prop); else newObj[i] = prop; } return newObj; }
4)方法4:使用jQuery.extend()
和jQuery.fn.extend()
請見:http://www.dbjr.com.cn/article/144424.htm
更多關(guān)于JavaScript相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《javascript面向?qū)ο笕腴T教程》、《JavaScript錯誤與調(diào)試技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript遍歷算法與技巧總結(jié)》及《JavaScript數(shù)學(xué)運算用法總結(jié)》
希望本文所述對大家JavaScript程序設(shè)計有所幫助。
相關(guān)文章
js父窗口關(guān)閉時子窗口隨之關(guān)閉完美解決方案
admin注銷的時候,或者main.html關(guān)閉的時候,如何讓打開的所有新窗口一起關(guān)閉,下面有個不錯的解決方案,大家可以參考下2014-04-04腳本吧 - 幻宇工作室用到j(luò)s,超強推薦share.js
腳本吧 - 幻宇工作室用到j(luò)s,超強推薦share.js...2006-12-12Bootstrap導(dǎo)航條可點擊和鼠標(biāo)懸停顯示下拉菜單
這篇文章主要為大家詳細介紹了Bootstrap導(dǎo)航條可點擊和鼠標(biāo)懸停顯示下拉菜單,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-11-11JavaScript常用代碼書寫規(guī)范的超全面總結(jié)
這篇文章給大家全面總結(jié)了JavaScript常用代碼的書寫規(guī)范,分別利用推薦和不推薦的兩種示例代碼讓大家更能直接的了解書寫規(guī)范,其實關(guān)于javascript代碼規(guī)范我們應(yīng)該遵循古老的原則:“能做并不意味著應(yīng)該做”,好了,下面我們就來一起看看吧。2016-09-09使用JS在瀏覽器中判斷當(dāng)前網(wǎng)絡(luò)連接狀態(tài)的幾種方法
本篇文章主要介紹了使用JS在瀏覽器中判斷當(dāng)前網(wǎng)絡(luò)狀態(tài)的幾種方法,非常具有實用價值,需要的朋友可以參考下2017-05-05