詳解JavaScript中Proxy與Object.defineProperty的區(qū)別
功能方面的區(qū)別:
Object.defineProperty:它是ES5引入的屬性定義方法,通過(guò)直接定義對(duì)象屬性的特性(如可枚舉性、可寫(xiě)性等),可以攔截屬性的讀取、寫(xiě)入和刪除操作。但它只能攔截對(duì)象的屬性訪問(wèn),對(duì)于對(duì)象的整體操作(如對(duì)整個(gè)對(duì)象的賦值或?qū)傩员闅v)并不會(huì)被攔截。
Proxy:它是ES6引入的代理機(jī)制,可以對(duì)整個(gè)對(duì)象進(jìn)行代理,攔截對(duì)象的各種操作,包括屬性訪問(wèn)、賦值、刪除、函數(shù)調(diào)用等。通過(guò)在代理對(duì)象上定義各種"陷阱"(trap)方法,可以自定義攔截行為,實(shí)現(xiàn)更細(xì)粒度的對(duì)象操作控制。
比如:
Object.defineProperty對(duì)整個(gè)對(duì)象進(jìn)行賦值,不會(huì)觸發(fā)set攔截
const obj = {}; Object.defineProperty(obj, 'name', { get() { console.log('訪問(wèn)name屬性'); return 'John'; }, set(value) { console.log('設(shè)置name屬性'); obj._name = value; } }); // 訪問(wèn)name屬性,觸發(fā)get攔截 console.log(obj.name); // 輸出: "訪問(wèn)name屬性" 和 "John" // 設(shè)置name屬性,觸發(fā)set攔截 obj.name = 'Alice'; // 輸出: "設(shè)置name屬性" // 對(duì)整個(gè)對(duì)象進(jìn)行賦值,不會(huì)觸發(fā)set攔截 obj = { age: 25 }; // 拋出TypeError: Assignment to constant variable.
輸出如下圖所示:
Object.defineProperty對(duì)整個(gè)對(duì)象進(jìn)行遍歷,不會(huì)觸發(fā)get攔截
const obj = { name: 'John', age: 25 }; Object.defineProperty(obj, 'name', { get() { console.log('訪問(wèn)name屬性'); return 'Alice'; } }); for (const key in obj) { console.log(key); // 輸出: "name" 和 "age" } console.log(obj.name); // 輸出: "訪問(wèn)name屬性" 和 "Alice"
輸出結(jié)果如下:
Proxy自定義攔截行為
const user = { name: 'John', age: 25, }; const protectedUser = new Proxy(user, { set(target, property, value) { if (property === 'age') { throw new Error('age屬性不可被修改'); } return Reflect.set(target, property, value); }, deleteProperty(target, property) { if (property === 'name') { throw new Error('name屬性不可被刪除'); } return Reflect.deleteProperty(target, property); }, }); console.log(protectedUser.name); // 輸出: "John" protectedUser.name = 'Alice'; // 不會(huì)拋出錯(cuò)誤,屬性賦值成功 console.log(protectedUser.name); // 輸出: "Alice" protectedUser.age = 30; // 拋出錯(cuò)誤,無(wú)法修改age屬性 delete protectedUser.name; // 拋出錯(cuò)誤,無(wú)法刪除name屬性
Proxy的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
- 更全面的攔截能力:Proxy可以攔截對(duì)象的更多操作,包括對(duì)屬性的讀取、賦值、刪除等,以及函數(shù)的調(diào)用等,提供了更細(xì)粒度的攔截控制。
- 可變性控制:Proxy可以用于控制對(duì)象的可變性,例如可以禁止對(duì)某些屬性進(jìn)行賦值或刪除,從而實(shí)現(xiàn)更嚴(yán)格的對(duì)象保護(hù)和約束。
缺點(diǎn)
- 兼容性問(wèn)題:Proxy是ES6引入的新特性,舊版本的JavaScript環(huán)境可能不支持Proxy,因此在一些特定的環(huán)境或需求下,使用Proxy可能會(huì)導(dǎo)致兼容性問(wèn)題。
- 性能開(kāi)銷:相比Object.defineProperty,Proxy的攔截機(jī)制更為復(fù)雜,因此在某些情況下可能會(huì)引入一定的性能開(kāi)銷。但對(duì)于大多數(shù)應(yīng)用場(chǎng)景來(lái)說(shuō),這種開(kāi)銷可以忽略不計(jì)。
到此這篇關(guān)于詳解JavaScript中Proxy與Object.defineProperty的區(qū)別的文章就介紹到這了,更多相關(guān)Proxy與Object.defineProperty區(qū)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript 完成注冊(cè)頁(yè)面表單校驗(yàn)的實(shí)例
下面小編就為大家?guī)?lái)一篇JavaScript 完成注冊(cè)頁(yè)面表單校驗(yàn)的實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-08-08javascript產(chǎn)生隨機(jī)數(shù)方法匯總
這篇文章主要介紹了javascript產(chǎn)生隨機(jī)數(shù)方法匯總的相關(guān)資料,需要的朋友可以參考下2016-01-01javascript如何判斷數(shù)組內(nèi)元素是否重復(fù)的方法集錦
javascript如何判斷數(shù)組內(nèi)元素是否重復(fù)的方法集錦...2007-02-02前端實(shí)現(xiàn)列表多條件查詢/搜索功能兩種實(shí)現(xiàn)方法
我們?cè)陂_(kāi)發(fā)過(guò)程中,特別是數(shù)據(jù)庫(kù)系統(tǒng)的開(kāi)發(fā)中經(jīng)常會(huì)遇到多條件的查詢狀況這篇文章主要給大家介紹了關(guān)于前端實(shí)現(xiàn)列表多條件查詢/搜索功能的兩種實(shí)現(xiàn)方法,需要的朋友可以參考下2024-08-08JS如何判斷瀏覽器類型和詳細(xì)區(qū)分IE各版本瀏覽器
本篇文章主要介紹了JS判斷瀏覽器類型和詳細(xì)區(qū)分IE各版本瀏覽器的代碼,非常具有實(shí)用價(jià)值,有興趣的可以了解一下。2017-03-03實(shí)現(xiàn)JavaScript高性能的數(shù)據(jù)存儲(chǔ)
本文主要對(duì)JavaScript的數(shù)據(jù)存儲(chǔ),產(chǎn)生性能問(wèn)題的原因,內(nèi)存泄露的幾種情況等做了簡(jiǎn)要分析介紹,需要的朋友可以看下2016-12-12javascript間隔定時(shí)器(延時(shí)定時(shí)器)學(xué)習(xí) 間隔調(diào)用和延時(shí)調(diào)用
這篇文章主要介紹了javascript間隔調(diào)用和延時(shí)調(diào)用示例,介紹setInterval方法和clearInterval方法的使用方法,大家參考使用吧2014-01-01各瀏覽器對(duì)document.getElementById等方法的實(shí)現(xiàn)差異解析
這篇文章主要是對(duì)各瀏覽器對(duì)document.getElementById等方法的實(shí)現(xiàn)差異進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2013-12-12詳解在IDEA中將Echarts引入web兩種方式(使用js文件和maven的依賴導(dǎo)入)
這篇文章主要介紹了在IDEA中將Echarts引入web兩種方式(使用js文件和maven的依賴導(dǎo)入),本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07