摘要:結(jié)構(gòu)化算法優(yōu)于的地方優(yōu)于的地方結(jié)構(gòu)化克隆可以復(fù)制對(duì)象。的克隆粒度將會(huì)跟原始對(duì)象相同,并且復(fù)制出來(lái)相同的像素?cái)?shù)據(jù)。企圖去克隆節(jié)點(diǎn)同樣會(huì)拋出異常。消息通道的傳遞是異步的,使用結(jié)構(gòu)化克隆算法。
JavaScript 深拷貝性能分析(漢化版)
JavaScript 深拷貝性能分析
Object.assign 方法只會(huì)拷貝源對(duì)象自身的并且可枚舉的屬性到目標(biāo)對(duì)象。該方法使用源對(duì)象的[[Get]]和目標(biāo)對(duì)象的[[Set]],所以它會(huì)調(diào)用相關(guān) getter 和 setter。
JSON.parse過(guò)去瀏覽器內(nèi)部傳遞的對(duì)象是使用JSON進(jìn)行序列化的。 現(xiàn)代瀏覽器序列化將使用結(jié)構(gòu)化克隆算法。這將會(huì)使更多對(duì)象可以被安全的傳遞。
JSON parse的優(yōu)缺點(diǎn)優(yōu)點(diǎn)
代碼簡(jiǎn)單
const obj = /* ... */ const copy = JSON.parse(JSON.stringify(obj))
缺點(diǎn)
如果對(duì)象復(fù)雜,你可能創(chuàng)建一個(gè)臨時(shí)的,很大的字符串,只是為了把它重新放回解析器。
無(wú)法解決處理循環(huán)對(duì)象, 如當(dāng)您構(gòu)建樹狀數(shù)據(jù)結(jié)構(gòu),其中一個(gè)節(jié)點(diǎn)引用其父級(jí),而父級(jí)又引用其子級(jí)。
const x = {}; const y = {x}; x.y = y; // Cycle: x.y.x.y.x.y.x.y.x... const copy = JSON.parse(JSON.stringify(x)); // throws!
諸如 Map, Set, RegExp, Date, ArrayBuffer 和其他內(nèi)置類型在進(jìn)行序列化時(shí)會(huì)丟失
結(jié)構(gòu)化克隆算法因?yàn)樗С职h(huán)圖的對(duì)象的序列化 ---對(duì)象可以引用在同一個(gè)圖中引用其他對(duì)象的對(duì)象。此外,在某些情況下,結(jié)構(gòu)化克隆算法可能比JSON更高效。
結(jié)構(gòu)化算法優(yōu)于JSON的地方
結(jié)構(gòu)化克隆可以復(fù)制 RegExp 對(duì)象。
結(jié)構(gòu)化克隆可以復(fù)制 Blob、File 以及 FileList 對(duì)象。
結(jié)構(gòu)化克隆可以復(fù)制 ImageData 對(duì)象。CanvasPixelArray
的克隆粒度將會(huì)跟原始對(duì)象相同,并且復(fù)制出來(lái)相同的像素?cái)?shù)據(jù)。
結(jié)構(gòu)化克隆可以正確的復(fù)制有循環(huán)引用的對(duì)象
結(jié)構(gòu)化克隆所不能做到的Error 以及 Function 對(duì)象是不能被結(jié)構(gòu)化克隆算法復(fù)制的;如果你嘗試這樣子去做,這會(huì)導(dǎo)致拋出 DATA_CLONE_ERR 的異常。
企圖去克隆 DOM 節(jié)點(diǎn)同樣會(huì)拋出 DATA_CLONE_ERROR 異常。
對(duì)象的某些特定參數(shù)也不會(huì)被保留
RegExp 對(duì)象的 lastIndex 字段不會(huì)被保留
屬性描述符,setters 以及 getters(以及其他類似元數(shù)據(jù)的功能)同樣不會(huì)被復(fù)制。例如,如果一個(gè)對(duì)象用屬性描述符標(biāo)記為 read-only,它將會(huì)被復(fù)制為 read-write,因?yàn)檫@是默認(rèn)的情況下。
原形鏈上的屬性也不會(huì)被追蹤以及復(fù)制。
symbols 不會(huì)被復(fù)制
MessageChannelChannel Messaging API的Channel Messaging接口允許我們創(chuàng)建一個(gè)新的消息通道,并通過(guò)它的兩個(gè)MessagePort 屬性發(fā)送數(shù)據(jù)。
消息通道的傳遞是異步的,使用結(jié)構(gòu)化克隆算法。
Note: 此特性在 Web Worker 中可用。
兼容性如下:
HTML5引入了 history.pushState() 和 history.replaceState() 方法,它們分別可以添加和修改歷史記錄條目。這些方法通常與window.onpopstate 配合使用。
pushState
history.pushState(data({a: "hi"}), name("tdy"), url("bar.html"))
改變?yōu)g覽器的url顯示,但是瀏覽器本身不會(huì)去做任何的改變。
history.replaceState() 參數(shù)和pushState一致,修改當(dāng)前頁(yè)面的信息
window.onpopstate
調(diào)用history.pushState()或者h(yuǎn)istory.replaceState()不會(huì)觸發(fā)popstate事件. popstate事件只會(huì)在瀏覽器某些行為下觸發(fā), 比如點(diǎn)擊后退、前進(jìn)按鈕(或者在JavaScript中調(diào)用history.back()、history.forward()、history.go()方法).信息保存在state屬性上
pushState或replaceState時(shí)需要復(fù)制一份狀態(tài)對(duì)象,這個(gè)狀態(tài)對(duì)象使用結(jié)構(gòu)化克隆而且是同步的。
最大儲(chǔ)存對(duì)象大小為640KB。
Safari 瀏覽器對(duì)replaceState調(diào)用的限制數(shù)量為 30 秒內(nèi) 100 次。
兼容性如下:
簡(jiǎn)潔明了
function structuralClone(obj) { return new Notification("", {data: obj, silent: true}).data } const obj = /* ... */ const clone = structuralClone(obj)
兼容性欠佳,并且,Safari 總是返回undefined。
最后如果您沒(méi)有循環(huán)對(duì)象,并且不需要保留內(nèi)置類型,則可以使用跨瀏覽器的JSON.parse(JSON.stringify())獲得最快的克隆性能。
如果你想要一個(gè)適當(dāng)?shù)慕Y(jié)構(gòu)化克隆,MessageChannel是你唯一可靠的跨瀏覽器的選擇。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/107252.html
摘要:判斷參數(shù)是否為待判斷的參數(shù)克隆一個(gè)對(duì)象要克隆的目標(biāo)對(duì)象克隆節(jié)點(diǎn),綁定事件的有問(wèn)題,暫不處理克隆在當(dāng)前作用域,在全局克隆其它對(duì)象,通過(guò)識(shí)別復(fù)制后的對(duì)象與原對(duì)象是否相同來(lái)決定傳不傳參數(shù),像數(shù)組是不能傳參數(shù)的使用防止對(duì)象重寫了方法支持節(jié)點(diǎn)克隆 (function(){ var toString=Object.prototype.toString,gObj={},cloneHelper=f...
摘要:優(yōu)點(diǎn)簡(jiǎn)單易實(shí)現(xiàn)缺點(diǎn)無(wú)法真正克隆對(duì)象深克隆實(shí)現(xiàn)通過(guò)遞歸克隆實(shí)現(xiàn)代碼輸出通過(guò)序列化實(shí)現(xiàn)代碼輸出結(jié)果分析采用深克隆能有效隔離源對(duì)象與克隆對(duì)象的聯(lián)系。 本文首發(fā)于cartoon的博客 ????轉(zhuǎn)載請(qǐng)注明出處:https://cartoonyu.github.io/cartoon-blog/post/java/java%E5%AE%9E%E7%8E%B0%E5%85%8B%E9%9A%86%E...
摘要:五作用的關(guān)鍵方法,用來(lái)從目標(biāo)節(jié)點(diǎn)克隆數(shù)據(jù)添加事件給克隆的元素注意采用數(shù)據(jù)分離的方法來(lái)保存上的事件和數(shù)據(jù),利用標(biāo)記每個(gè)元素,然后在內(nèi)存上,將每個(gè)元素相關(guān)的數(shù)據(jù)放到內(nèi)存中,然后在和內(nèi)存的數(shù)據(jù)之間建立映射。 showImg(https://segmentfault.com/img/remote/1460000018991125); 前言:這篇講完后,jQuery的文檔處理就告一段落了,有空我...
摘要:原始類型對(duì)象指的是字符串?dāng)?shù)值布爾值,引用類型對(duì)象指的是數(shù)組對(duì)象函數(shù)。既然對(duì)象分為這兩類,他們的復(fù)制克隆也是有差別的??偨Y(jié)根據(jù)上面的情況,另外,克隆引用對(duì)象必須采用完整克隆深度克隆,包括對(duì)象的值也是一個(gè)對(duì)象也要進(jìn)行完整克隆深度克隆。 前言 之前有人問(wèn)我如何克隆一個(gè)JS對(duì)象,我當(dāng)時(shí)沒(méi)答上來(lái);過(guò)后我查資料弄懂了這個(gè)問(wèn)題,現(xiàn)在整理成文。 正文 JavaScript的一切實(shí)例都是對(duì)象,但他們也分...
摘要:在聊以下簡(jiǎn)稱深度克隆之前,我們先來(lái)了解一下中對(duì)象的組成??寺』蛘呖截惙譃榉N淺度克隆深度克隆。淺度克隆基本類型為值傳遞,對(duì)象仍為引用傳遞。 該文轉(zhuǎn)載自http://www.cnblogs.com/zichi/p/4568150.html,有部分修改。 在聊JavaScript(以下簡(jiǎn)稱js)深度克隆之前,我們先來(lái)了解一下js中對(duì)象的組成。在 js 中一切實(shí)例皆是對(duì)象,具體分為 原始類型 ...
閱讀 1119·2021-11-18 10:02
閱讀 1374·2021-09-23 11:22
閱讀 2684·2021-08-21 14:08
閱讀 1703·2019-08-30 15:55
閱讀 1786·2019-08-30 13:45
閱讀 3304·2019-08-29 16:52
閱讀 3160·2019-08-29 12:18
閱讀 1707·2019-08-26 13:36