使用小程序ES6新特性 新增了Proxy和 Reflect特性
2017年6月14日,小程序ES6新特性已經(jīng)是當(dāng)下微信小程序開發(fā)最熱門的話題,下面將從多方面來談?wù)勑〕绦駿S6新特性相關(guān)的內(nèi)容。
6月14日消息,據(jù)彭博社報(bào)道,為了與新東家沃爾瑪(Walmart)融合得更加順暢,Jet.com(去年8月被沃爾瑪以33億美元收購)正計(jì)劃逐步剔除自己平臺上所售的Costco旗下品牌產(chǎn)品。
6月18日,永輝將在福州開出第一家永輝生活店。值得注意的是,這也是永輝首家24小時(shí)營業(yè)門店。據(jù)了解,這家24小時(shí)門店商品由永輝物流統(tǒng)一配送,沒有熟食但提供蔬菜水果以及冷凍冰鮮類商品。
元編程是指的是開發(fā)人員對 “語言本身進(jìn)行編程”。一般是編程語言暴露了一些API,供開發(fā)人員來操作語言本身的某些特性。
從ES6開始,新增了Proxy和 Reflect特性,擴(kuò)展了元編程(Meta Programming)能力,允許攔截并定制基礎(chǔ)語言操作行為(比如,屬性查找,賦值,枚舉,函數(shù)調(diào)等)。
Proxy(代理)
Proxy是ES6加入的一個(gè)新特性,它可以 “代理” 對象的原生行為,替換為執(zhí)行自定義行為。
Proxy可以理解成在目標(biāo)對象之前架設(shè)一層“攔截”,外界對該對象的訪問,都必須先通過這層攔截,因此提供了一種機(jī)制,可以對外界的訪問進(jìn)行過濾和改寫。Proxy這個(gè)詞的原意是代理,用在這里表示由它來“代理”某些操作,可以譯為“代理器”。
Proxy 對象用來為基礎(chǔ)操作(例如:屬性查找、賦值、枚舉、方法調(diào)用等)定義用戶自定義行為。
創(chuàng)建一個(gè)Proxy對象:
target:目標(biāo)對象,可以是任意類型的對象,比如數(shù)組,函數(shù),甚至是另外一個(gè)代理對象。
handlert:處理器對象,包含了一組代理方法,分別控制所生成代理對象的各種行為。
Proxy對象的方法:
Proxy.revocable(target, handler):用來創(chuàng)建一個(gè)可撤銷的代理對象。
處理器對象一共有14種可代理方法:
handler.getPrototypeOf():在讀取代理對象的原型時(shí)觸發(fā)該操作,比如在執(zhí)行 Object.getPrototypeOf(proxy) 時(shí)。
handler.setPrototypeOf():在設(shè)置代理對象的原型時(shí)觸發(fā)該操作,比如在執(zhí)行 Object.setPrototypeOf(proxy, null) 時(shí)。
handler.isExtensible():在判斷一個(gè)代理對象是否是可擴(kuò)展時(shí)觸發(fā)該操作,比如在執(zhí)行 Object.isExtensible(proxy) 時(shí)。
handler.preventExtensions():在讓一個(gè)代理對象不可擴(kuò)展時(shí)觸發(fā)該操作,比如在執(zhí)行 Object.preventExtensions(proxy) 時(shí)。
handler.getOwnPropertyDescriptor():在獲取代理對象某個(gè)屬性的屬性描述時(shí)觸發(fā)該操作,比如在執(zhí)行 Object.getOwnPropertyDescriptor(proxy, “foo”) 時(shí)。
handler.defineProperty():在定義代理對象某個(gè)屬性時(shí)的屬性描述時(shí)觸發(fā)該操作,比如在執(zhí)行 Object.defineProperty(proxy, “foo”, {}) 時(shí)。
handler.has():在判斷代理對象是否擁有某個(gè)屬性時(shí)觸發(fā)該操作,比如在執(zhí)行 “foo” in proxy 時(shí)。
handler.get():在讀取代理對象的某個(gè)屬性時(shí)觸發(fā)該操作,比如在執(zhí)行 proxy.foo 時(shí)。
handler.set():在給代理對象的某個(gè)屬性賦值時(shí)觸發(fā)該操作,比如在執(zhí)行 proxy.foo = 1 時(shí)。
handler.deleteProperty():在刪除代理對象的某個(gè)屬性時(shí)觸發(fā)該操作,比如在執(zhí)行 delete proxy.foo 時(shí)。
handler.enumerate():在遍歷代理對象的屬性時(shí)觸發(fā)該操作,比如在執(zhí)行 for(i in proxy){} 時(shí)。
handler.ownKeys():在獲取代理對象的所有屬性鍵時(shí)觸發(fā)該操作,比如在執(zhí)行 Object.getOwnPropertyNames(proxy) 時(shí)。
handler.apply():在調(diào)用一個(gè)目標(biāo)對象為函數(shù)的代理對象時(shí)觸發(fā)該操作,比如在執(zhí)行 proxy() 時(shí)。
handler.construct():在給一個(gè)目標(biāo)對象為構(gòu)造函數(shù)的代理對象構(gòu)造實(shí)例時(shí)觸發(fā)該操作,比如在執(zhí)行new proxy() 時(shí)。
攔截屬性值的讀取操作:
上面代碼中,Proxy(代理)對象定義一個(gè)target和一個(gè)handle,handle實(shí)現(xiàn)了一個(gè)get捕捉方法。通過這個(gè)方法,被代理的對象對于未定義的屬性,不再返回undefined,而是返回一個(gè)42的數(shù)字。
攔截屬性值的賦值操作:
上面代碼中,設(shè)置了set的處理函數(shù),如果我們偵聽的對象的屬性被更改,那這個(gè)處理程序就會(huì)被調(diào)用,同時(shí)通過參數(shù)能夠得知是哪個(gè)屬性被更改,更改為了什么值。
同一個(gè)攔截器函數(shù),可以設(shè)置攔截多個(gè)操作:
Proxy.revocable方法用來創(chuàng)建一個(gè)可撤銷的代理對象,一旦某個(gè)代理對象被撤銷,它將變的幾乎完全不可用,在它身上執(zhí)行任何的可代理操作都會(huì)拋出 TypeError 異常。
Reflect(反射)
ES6 中引入的Reflect是另一個(gè)元編程的特性,它使得我們可以直接操縱對象的原生行為。Reflect可操縱的行為與Proxy可代理的行為是一一對應(yīng)的,這使得可以在Proxy的自定義方法中方便的使用Reflect調(diào)用原生行為。
Reflection(反射)促進(jìn)元編程的一種很有價(jià)值的語言特性,它可以在程序運(yùn)行時(shí)動(dòng)態(tài)展現(xiàn)程序本身的特性。
Reflect 對象提供了14個(gè)靜態(tài)方法,它們的名字剛好和那14個(gè)代理處理器方法的名字相同,這14個(gè)方法中有幾個(gè)剛好在 Object 對象身上也存在同名方法,雖然它們功能類似,但也存在細(xì)微差異。
Reflect.apply():對一個(gè)函數(shù)進(jìn)行調(diào)用操作,同時(shí)可以傳入一個(gè)數(shù)組作為調(diào)用參數(shù)。和 Function.prototype.apply() 功能類似。
Reflect.construct():對構(gòu)造函數(shù)進(jìn)行 new 操作,相當(dāng)于執(zhí)行 new target(…args)。
Reflect.defineProperty():和 Object.defineProperty() 類似。
Reflect.deleteProperty():刪除對象的某個(gè)屬性,相當(dāng)于執(zhí)行 delete target[name]。
Reflect.enumerate():該方法會(huì)返回一個(gè)包含有目標(biāo)對象身上所有可枚舉的自身字符串屬性以及繼承字符串屬性的迭代器,for…in 操作遍歷到的正是這些屬性。
Reflect.get():獲取對象身上某個(gè)屬性的值,類似于 target[name]。
Reflect.getOwnPropertyDescriptor():類似于 Object.getOwnPropertyDescriptor()。
Reflect.getPrototypeOf(): 類似于 Object.getPrototypeOf()。
Reflect.has():判斷一個(gè)對象是否存在某個(gè)屬性,和 in 運(yùn)算符 的功能完全相同。
Reflect.isExtensible():類似于 Object.isExtensible()。
Reflect.ownKeys():返回一個(gè)包含所有自身屬性(不包含繼承屬性)的數(shù)組。
Reflect.preventExtensions():類似于 Object.preventExtensions()。
Reflect.set():設(shè)置對象身上某個(gè)屬性的值,類似于 target[name] = val。
Reflect.setPrototypeOf():類似于 Object.setPrototypeOf()。
上面代碼中,Proxy方法攔截target對象的屬性賦值行為,采用Reflect.set方法將值賦值給對象的屬性。
為什么要使用Reflect:
將Object對象的一些明顯屬于語言內(nèi)部的方法(比如Object.defineProperty),放到Reflect對象上?,F(xiàn)階段,某些方法同時(shí)在Object和Reflect對象上部署,未來的新方法將只部署在Reflect對象上。
修改某些Object方法的返回結(jié)果,讓其變得更合理。比如,Object.defineProperty(obj, name, desc)在無法定義屬性時(shí),會(huì)拋出一個(gè)錯(cuò)誤,而Reflect.defineProperty(obj, name, desc)則會(huì)返回false。
讓Object操作都變成函數(shù)行為。某些Object操作是命令式,比如name in obj和delete obj[name],而Reflect.has(obj, name)和Reflect.deleteProperty(obj, name)讓它們變成了函數(shù)行為。
Reflect對象的方法與Proxy對象的方法一一對應(yīng),只要是Proxy對象的方法,就能在Reflect對象上找到對應(yīng)的方法。這就讓Proxy對象可以方便地調(diào)用對應(yīng)的Reflect方法,完成默認(rèn)行為,作為修改行為的基礎(chǔ)。也就是說,不管Proxy怎么修改默認(rèn)行為,你總可以在Reflect上獲取默認(rèn)行為。
上面代碼中,每一個(gè)Proxy對象的攔截操作(get、delete、has),內(nèi)部都調(diào)用對應(yīng)的Reflect方法,保證原生行為能夠正常執(zhí)行。添加的工作,就是將每一個(gè)操作輸出一行日志。有了Reflect對象以后,很多操作會(huì)更易讀。
-
微信小程序商城系統(tǒng)開發(fā)其實(shí)很簡單
微信小程序商城系統(tǒng)開發(fā)其實(shí)很簡單,只需要五步就可以完成,整個(gè)過程包括開發(fā)、上線、發(fā)布都可以輕松搞定...詳情
-
微信小程序商城系統(tǒng)免費(fèi)注冊體驗(yàn)
微信小程序商城系統(tǒng)免費(fèi)注冊體驗(yàn),接下來是微信小程序的時(shí)代,這一波紅利在不抓住互聯(lián)網(wǎng)就再也沒什么機(jī)會(huì)了...詳情
想了解更多微信小程序開發(fā)和微信小程序大全都可以進(jìn)入微信小程序商城系統(tǒng)開發(fā)了解。
第二部分:如何開通一個(gè)小商店