從層次來看,物件的複製可以簡單地分為淺複製和深複製,顧名思義,淺複製是指只複製一層物件的屬性,不會複製物件中的物件的屬性,物件的深複製會複製物件中層層嵌套的物件的屬性。本文是我在複製物件方面的一些心得總結,由淺複製到深複製,有興趣的朋友一起學習吧
前言
從層次來看,物件的複製可以簡單地分為淺複製和深複製,顧名思義,淺複製是指只複製一層物件的屬性,不會複製物件中的物件的屬性,物件的深複製會複製對象中層層嵌套的物件的屬性。
在複製物件時,除了要複製物件的屬性外,還要兼顧到是否保留了物件的constructor屬性,是否對每一種資料類型(Javascript常見的資料類型有String, Number,Boolean,Data,RegExp,Array,Funtion,Object)都實現正確的複製。在專案中,我們可以根據實際情況,決定需要實現什麼樣程度的複製。
本文是我在複製物件方面的一些心得總結,由淺複製到深複製,由只複製簡單屬性到複製Function,RegExp等複雜屬性,層層遞進。如有陳述不當之處,煩請指出,不勝感激。
正文
淺複製
淺複製只會依序複製物件的每一個屬性,不會對這些屬性進行遞歸複製。下面是一個簡單的淺複製實作。
//对象浅复制 function shadowCopy(obj){ if(typeof obj !== 'object') return obj; for(var prop in obj){ if(obj.hasOwnProperty(prop)){ newObj[prop] = obj[prop]; } } return newObj; }
仔細觀察,不難發現上述方法的缺陷:
1.無法正確實作陣列的淺複製
2.複製操作遺失了物件的constructor屬性
好,我們現在已經發現了問題所在,只需針對性地解決,一個還算完美的淺複製物件的方法就誕生了!
//对象浅复制 function shadowCopy(obj){ if(typeof obj !== 'object') return ; var newObj; //保留对象的constructor属性 if(obj.constructor === Array){ newObj = []; } else { newObj = {}; newObj.constructor = obj.constructor; } for(var prop in obj){ if(obj.hasOwnProperty(prop)){ newObj[prop] = obj[prop]; } } return newObj; }
瀏覽器中測試一下:
var arr1 = [0,1,2]; console.log(arr1); console.log(shadowCopy(arr1)); var arr2 = [0,1,2,[3,4,5]], arr2Copy = shadowCopy(arr2); console.log(arr2); console.log(arr2Copy); arr2Copy[3][0] = 6; console.log(arr2[3][0]); //6
Good! 可以正確實作數組複製和並且保留constructor了,但細心的你一定發現了,淺複製後的對象的arr2Copy[3] 和arr2[3] 指向的是一個對象,改變其中一個,同時也會改變另一個。我們想要實現的是 複製,但這不是複製呀!
這是淺複製的一個弊端所在,接下讓我們看看深複製是怎麼解決這個問題的。
深複製
深複製需要層層遞歸,複製物件的所有屬性,包括物件屬性的屬性的屬性....(暈~)
如果只是需要簡單地複製物件的屬性,而不用考慮它的constructor,也不用考慮函數,正則,Data等特殊資料類型,那麼這裡有一個深複製的小trick,兩行程式碼即可:
function deepCopy(obj){ if(typeof obj !== "object"){ return ;} var str = JSON.stringify(obj); return JSON.parse(str); }
大多數情況下,上面的就可以滿足要求了,但一些時候,我們需要把函數,正則等特殊資料類型也考慮在內,或者當前環境不支持JSON時,上面的方法也就不適用了。這時,我們可以透過遞歸來實現物件的深層複製,如下:
function deepCopy(obj){ if(typeof obj !== "object"){ return ;} var newObj; //保留对象的constructor属性 if(obj.constructor === Array){ newObj = []; } else { newObj = {}; newObj.constructor = obj.constructor; } for(var prop in obj){ if(typeof obj[prop] === 'object'){ if(obj[prop].constructor === RegExp ||obj[prop].constructor === Date){ newObj[prop] = obj[prop]; } else { //递归 newObj[prop] = deepCopy(obj[prop]); } } else { newObj[prop] = obj[prop]; } } return newObj; }
先用上面的範例測試:
棒!可以正確實現多維數組的複製,再看是否能實現函數和正規的複製:
function Person(name){ this.name = name; this.age = age; this.search = new RegExp(name); this.say = function(){ console.log(this.name + "今年" + this.age + "岁了"); } } var p1 = new Person("Claiyre",20), p2 = deepCopy(p1); console.log(p1); console.log(p2); p2.age = 22; p1.say(); p2.say();
圓滿完成! !
稍加整理,我們就可以得到一個較為通用的js物件複製函數:
function deepCopy(obj){ var newObj = obj.constructor === Array ? []:{}; newObj.constructor = obj.constructor; if(typeof obj !== "object"){ return ; } else if(window.JSON){ //若需要考虑特殊的数据类型,如正则,函数等,需把这个else if去掉即可 newObj = JSON.parse(JSON.stringify(obj)); } else { for(var prop in obj){ if(obj[prop].constructor === RegExp ||obj[prop].constructor === Date){ newObj[prop] = obj[prop]; } else if(typeof obj[prop] === 'object'){ //递归 newObj[prop] = deepCopy(obj[prop]); } else { newObj[prop] = obj[prop]; } } } return newObj; }
##結語
物件導向的程式語言,其核心是對象,因此深入了解對象的相關操作,縱向比較異同,對學習過程是極有好處的。以上是JavaScript物件的深淺複製實例詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

JavaScript是現代網站的核心,因為它增強了網頁的交互性和動態性。 1)它允許在不刷新頁面的情況下改變內容,2)通過DOMAPI操作網頁,3)支持複雜的交互效果如動畫和拖放,4)優化性能和最佳實踐提高用戶體驗。

C 和JavaScript通過WebAssembly實現互操作性。 1)C 代碼編譯成WebAssembly模塊,引入到JavaScript環境中,增強計算能力。 2)在遊戲開發中,C 處理物理引擎和圖形渲染,JavaScript負責遊戲邏輯和用戶界面。

JavaScript在網站、移動應用、桌面應用和服務器端編程中均有廣泛應用。 1)在網站開發中,JavaScript與HTML、CSS一起操作DOM,實現動態效果,並支持如jQuery、React等框架。 2)通過ReactNative和Ionic,JavaScript用於開發跨平台移動應用。 3)Electron框架使JavaScript能構建桌面應用。 4)Node.js讓JavaScript在服務器端運行,支持高並發請求。

Python更適合數據科學和自動化,JavaScript更適合前端和全棧開發。 1.Python在數據科學和機器學習中表現出色,使用NumPy、Pandas等庫進行數據處理和建模。 2.Python在自動化和腳本編寫方面簡潔高效。 3.JavaScript在前端開發中不可或缺,用於構建動態網頁和單頁面應用。 4.JavaScript通過Node.js在後端開發中發揮作用,支持全棧開發。

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。1)C 用于解析JavaScript源码并生成抽象语法树。2)C 负责生成和执行字节码。3)C 实现JIT编译器,在运行时优化和编译热点代码,显著提高JavaScript的执行效率。

JavaScript在現實世界中的應用包括前端和後端開發。 1)通過構建TODO列表應用展示前端應用,涉及DOM操作和事件處理。 2)通過Node.js和Express構建RESTfulAPI展示後端應用。

JavaScript在Web開發中的主要用途包括客戶端交互、表單驗證和異步通信。 1)通過DOM操作實現動態內容更新和用戶交互;2)在用戶提交數據前進行客戶端驗證,提高用戶體驗;3)通過AJAX技術實現與服務器的無刷新通信。

理解JavaScript引擎內部工作原理對開發者重要,因為它能幫助編寫更高效的代碼並理解性能瓶頸和優化策略。 1)引擎的工作流程包括解析、編譯和執行三個階段;2)執行過程中,引擎會進行動態優化,如內聯緩存和隱藏類;3)最佳實踐包括避免全局變量、優化循環、使用const和let,以及避免過度使用閉包。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

Dreamweaver CS6
視覺化網頁開發工具

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器

SublimeText3漢化版
中文版,非常好用