Javascript Proxy對象 簡介

Javascript Proxy對象 簡介

本文轉載自:眾成翻譯
譯者:eJayYoung
鏈接:http://www.zcfy.cc/article/4755
原文:https://blog.campvanilla.com/advanced-guide-javascript-proxy-objects-introduction-301c0fce9432

Javascript Proxy對象

改變你操作對象的方式

Proxies 是Javasript對象的中間件

…或者說至少是那種很早的版本。

ES6 中引入Proxies,讓你可以自定義Object的基本操作。例如,get就是Object的基礎操作方法。

const obj = {val: 10
};
console.log(obj.val);

這里,console.log()表達式在對象obj上執行get方法來獲取val的值。

另一個對象的基本操作方法是 set

const obj = {val: 10
};
obj.val2 = 20;

這里,set方法用來給對象obj設置一個新的值。


如何創建Proxy?

const proxiedObject = new Proxy(initialObj, handler);

調用Proxy構造函數,new Proxy()將返回一個對象,不僅包含了initialObj里的值,而且其基本操作(如getset)現在可以通過handler對象來指定一些自定義邏輯。

我們寫個例子來理解這個概念,

const handler = {get: function() {console.log('A value has been accessed');}
}const initialObj = {id: 1,name: 'Foo Bar'
}const proxiedObj = new Proxy(initialObj, handler);console.log(proxiedObj.name);

現在,如果我們沒有構造一個Proxy對象,執行第14行的console.log(proxiedObj.name)會在控制臺輸出 “Foo Bar”。

不過現在我們定義了一個Proxy,并在第三行get方法中定義了一些自定義邏輯。

現在執行console.log(proxiedObj.name)會在控制臺輸出 “A value has been accessed”。

仔細看,你會發現控制臺中實際上有兩條記錄。 “A value has been accessed” 和 undefined。 為什么?��

get運算符的默認實現是返回Object中存儲的值。由于我們將它重寫為只記錄一條語句,該值永遠不會返回,因此第14行的console.log()輸出undefined

讓我們來解決這個問題!

get運算符有兩個參數 - 對象本身和被訪問的屬性。

const handler = {get: function(obj, prop) {console.log('A value has been accessed');return obj[prop]; // 返回訪問的key在obj的值}
}const initialObj = {id: 1,name: 'Foo Bar'
}const proxiedObj = new Proxy(initialObj, handler);console.log(proxiedObj.name);

返回屬性值


返回屬性值 — 控制臺的輸出

好多了吧! ��

我們為get提供的自定義覆蓋被稱為“攔截器”(大概基于操作系統攔截的概念)。 handler對象基本上是一個包含一組“攔截”的對象,每當訪問對象屬性時都會被觸發。

我們給set也添加一個“攔截器”。 我們將做同樣的事情 - 任何時候設置一個值,我們將記錄被修改的屬性,以及為該鍵設置的值。

set操作符有三個參數 - 對象本身,被訪問的屬性和為該屬性設置的值。

const handler = {get: function(obj, prop) {console.log('A value has been accessed');return obj[prop];},set: function(obj, prop, value) {console.log(`${prop} is being set to ${value}`);}
}const initialObj = {id: 1,name: 'Foo Bar'
}const proxiedObj = new Proxy(initialObj, handler);proxiedObj.age = 24

添加set “攔截器”

這里,在第18行進行的訪問將觸發第6行定義的功能,該功能將記錄正在訪問的屬性和正在設置的值。

Set “攔截器”?—— 控制臺的輸出


一個真實的例子

假設我們有一個定義叫person的對象

const person = {id: 1,name: 'Foo Bar'
};

如果我們想讓這個對象的id屬性是一個私有屬性呢? 沒人能夠通過person.id訪問這個屬性,如果有人這樣做,我們需要拋出一個錯誤。 我們將如何做到這一點?

讓Proxies來拯救吧!����?��

我們所需要做的就是給這個對象創建一個Proxy,并覆蓋get運算符來阻止我們訪問id屬性!

const handler = {get: function(obj, prop) {if (prop === 'id') { // Check if the id is being accessedthrow new Error('Cannot access private properties!'); // Throw an error} else {return obj[prop]; // If it's not the id property, return it as usual}}
}const person = {id: 1,name: 'Foo Bar'
}const proxiedPerson = new Proxy(person, handler);console.log(proxiedPerson.id);

阻止訪問私有屬性

這里,在我們給get創建的“攔截器”,我們檢查被訪問的屬性是否是id屬性,如果是的話,我們會拋出一個錯誤。 否則,我們照常返回值。

私有屬性?—?控制臺輸出


另一個極好的用例是校驗。 通過設置set“攔截器”,我們可以在設置值之前添加自定義驗證。 如果該值不符合驗證,我們可以拋出一個錯誤!

const handler = {set: function(obj, prop, value) {if (typeof value !== 'string') {throw new Error('Only string values can be stored in this object!');} else {obj[prop] = value;}}
}const obj = {};const proxiedObj = new Proxy(obj, handler);console.log(proxiedObj); // This will log an empty object
proxiedObj.name = 'Foo Bar'; // This should be allowed
console.log(proxiedObj); // This will log an object with the name property setproxiedObj.age = 24; // This will throw an error.

自定義對象的屬性校驗

自定義校驗 - 控制臺輸出


在上面的例子中,我們已經看到了getset“陷阱”。 實際上可以設置更多的“陷阱”。 你可以在這里找到整個列表。

Proxy對象只是在閱讀關于它們的這篇文章之后才進入我的視野,我已經可以在我每天寫的代碼中看到它們的用處了!

如果你之前在項目或工作中使用過Proxies,我很樂意聽到!��

~最后~


如果您覺得這篇文章對您有用,請點個贊��!

在什么地方卡住了,需要更多的幫助,還是只想打個招呼? 在Hashnode 給我直接發問題,或者在Twitter上Call我。 你也可以在Github上找到我。��

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/539683.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/539683.shtml
英文地址,請注明出處:http://en.pswp.cn/news/539683.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

App架構經驗總結

原文地址:http://www.iteye.com/news/31472-------------------------------------------------------------架構因人而異,不同的架構師大多會有不同的看法;架構也因項目而異,不同的項目需求不同,相應的架構也會不同。…

python數字排序 循環_【python-leetcode448-循環排序】找到所有數組中消失的數字

問題描述:給定一個范圍在 1 ≤ a[i] ≤ n ( n 數組大小 ) 的 整型數組,數組中的元素一些出現了兩次,另一些只出現一次。找到所有在 [1, n] 范圍之間沒有出現在數組中的數字。您能在不使用額外空間且時間復雜度為O(n)的情況下完成這個任務嗎…

saiku+kettle整合(六)olap操作

title: saikukettle整合(六)olap操作 tags: categories: saiku date: 2016-08-25 18:18:54 使用saiku可以對應使用相關olap操作 OLAP的基本操作 我們已經知道OLAP的操作是以查詢——也就是數據庫的SELECT操作為主,但是查詢可以很復雜&#xf…

攜程Docker實踐

原文地址:http://www.iteye.com/news/31468 請點擊原文閱讀 ---------------------以下是原文---------------------- 從去年底開始,攜程開始計劃把Docker引入到攜程的云平臺,這是系統研發部一部分的工作任務,攜程系統研…

mysql全文索引thinkphp_ThinkPHP5 使用迅搜 (XunSearch) 實現全文檢索實例指導

前期準備入坑了一天,折騰的無語,個人觀點:【文檔太差,適合學習思路,不建議入坑】背景最近在整理全文檢索解決方案注意到 xunsearch 的評價很高,在此記錄一番場景描述此處作為對 xunsearch 的初次使用&#…

為何有些程序員總是想要“干掉”產品經理?

好了,我準備去和產品經理做斗爭去了,請祝我好運吧!小編花了大量時間收集了很多干貨編程學習資源,其中資源包括 算法,大數據,人工智能,Python,Android,iOS,Jav…

多個left join 產生多個結果

select a.*,to_char(To_date(20160403000000, yyyyMMddhh24miss),yyyy/mm/dd) as omc_start_time,to_char(To_date(20160404000000, yyyyMMddhh24miss),yyyy/mm/dd) as omc_end_time,ROUND(sc."切換成功率",2) AS "OMC-源小區切換成功率%",ROUND(sc."…

查看進程占用,并kill掉

今天發現8899端口被占,服務器啟動失敗,用了下面的命令解決。 [rootltesqm Toolbox]# netstat -tunlp |grep 8899 tcp 0 0 :::8899 :::* LISTEN 28279/java [rootltesqm Toolbox]…

Spark算子篇 --Spark算子之combineByKey詳解

一。概念 rdd.combineByKey(lambda x:"%d_" %x, lambda a,b:"%s%s" %(a,b), lambda a,b:"%s$%s" %(a,b))三個參數(都是函數)第一個參數:給定一個初始值,用函數生成初始值。第二個參數:c…

mysql proxy 主從_【MYSQL知識必知必會】MySQL主從復制讀寫分離(基于mysql-proxy實現)...

MySQL主從復制讀寫分離(基于mysql-proxy實現)http://mirror.bit.edu.cn/mysql/Downloads/MySQL-Proxy/mysql-proxy-0.8.4-linux-glibc2.3-x86-64bit.tar.gz解壓tar zxvf mysql-proxy-0.8.4-linux-glibc2.3-x86-64bit.tar.gz創建mysql-proxy帳號并授權分別在主從數據庫中創建mys…

SecureCRT防止自動斷開

今天在寧波連接上海的linux庫,是外網訪問內網,使用了nat123這個軟件映射的。 發現SecureCRT連接后,過幾分鐘就自動斷開,導致使用SecureCRT做跳轉機的其他應用使用起來很不方便。 于是設置了下SecureCRT。

mysql 主主結構_高性能mysql主主架構

(3)配置參數說明server-id:ID值唯一的標識了復制群集中的主從服務器,因此它們必須各不相同。master_id必須為1到232–1之間的一個正整數值,slave_id值必須為2到232–1之間的一個正整數值。log-bin:表示打開binlog,打開該選項才可以…

解決ios編譯swift報錯pcm was built: mtime changed

問題 編譯ios工程失敗時,其中的幾個swift文件報以下錯 /Users/tomes/code/project/xxx.swift File /Users/tomes/Library/Developer/Xcode/DerivedData/Spec-dgyhrnmgvfkjkqbboklnfgrudqip/Build/Products/Debug-iphoneos/xxxx.framework/Headers/xxxx.h has been…

AI工程師職業規劃和學習路線完整版

AI工程師職業規劃和學習路線完整版 如何成為一名機器學習算法工程師 成為一名合格的開發工程師不是一件簡單的事情,需要掌握從開發到調試到優化等一系列能 力,這些能力中的每一項掌握起來都需要足夠的努力和經驗。而要成為一名合格的機器學習算法工程師&…

oracle 多個with as

主要看多個with的格式 [sql] view plaincopy WITH T3 AS ( SELECT T1.ID, T1.CODE1, T2.DESCRIPTION FROM TB_DATA T1, TB_CODE T2 WHERE T1.CODE1 T2.CODE ), T4 AS ( SELECT T1.ID, T1.CODE2, T2.DESCRIPTION FROM TB_DATA T1, TB_CODE T2 WHERE T1.C…

mysql主鍵 命中率_mysql主鍵問題

MySQL主鍵一. MySQL主鍵設計原則MySQL主鍵應當是對用戶沒有意義的。MySQL主鍵應該是單列的,以便提高連接和篩選操作的效率(當然復合主鍵是可以的,只是不建議)永遠也不要更新MySQL主鍵MySQL主鍵不應包含動態變化的數據,如時間戳、創建時間列、…

Centos7常用命令[掛載文件系統]

Centos7常用命令[掛載文件系統]------------------------------------------------------------------------------# 掛載一個叫做hda2的盤-確定目錄/mnt/hda2已經存在[rootlocalhost ~]# mount /dev/hda2 /mnt/hda2# 卸載一個叫做hda2的盤-先從掛載點/mnt/hda2退出[rootlocalh…

hadoop SecondNamenode

一、定義 * The Secondary Namenode is a helper to the primary Namenode. * The Secondary is responsible for supporting periodic checkpoints * of the HDFS metadata. The current design allows only one Secondary * Namenode per HDFs cluster. * The Secondary Nam…

Tensorflow Python API 翻譯(sparse_ops)

作者:chen_h 微信號 & QQ:862251340 微信公眾號:coderpai 我的博客:請點擊這里計劃現將 tensorflow 中的 Python API 做一個學習,這樣方便以后的學習。 原文鏈接該章介紹有關稀疏張量的API稀疏張量表示對于多維稀疏…

高性能mysql 小查詢_高性能MySql進化論(十一):常見查詢語句的優化

總結一下常見查詢語句的優化方式1 COUNT1. COUNT的作用 COUNT(table.filed)統計的該字段非空值的記錄行數 COUNT(*)或者是COUNT(not nullable field) 統計的是全表的行數如果要是統計全表記錄數,COUNT(*)效率會比COUNT(not nullable fie…