? ? ? proxy用于修改某些操作的默認行為翰灾,等同于在語言層面上修改缕粹,所以屬于元編程,即對編程語言進行編程纸淮。proxy可以理解為在目標對象之前設(shè)立一層攔截平斩,外界對該對象的訪問都必須通過這層攔截,因此對外界的訪問進行過濾或修改咽块,也可以說成是對某些操作進行識別或者修改绘面。
? ? ? ES6中proxy函數(shù)的表現(xiàn)形式:var proxy = new Proxy(target,handler)。new Proxy()表示生成一個proxy實例侈沪,target表示攔截的對象揭璃,handler表示一個配置對象,包含著為每個需要被攔截的行為提供對應(yīng)的處理函數(shù)亭罪,handler如果沒有任何設(shè)置那么直通原對象瘦馍。
? ? ? 下面是一些設(shè)置的操作:get(target,propKey,reciver)攔截對象屬性的獲取,但是如果一個屬性被配置不可寫和不可配置的話那么該屬性就不能被代理应役;set(target,propKey,value,reciver)攔截對象屬性的設(shè)置情组;has(target,propKey)攔截propKey in proxy的操作,返回一個布爾值,但是面對不可配置的屬性依然會報錯箩祥,而且has針對for..in無效院崇;deleteProperty(target,propKey)攔截 delete proxy[propKey] 的操作,返回一個布爾值袍祖,如果這個方法拋出錯誤或者返回false當前屬性就無法被delete命令刪除(屬性如果是不可配置的刪除會報錯)底瓣;ownkeys(target,propkey)攔截Object.getownPropertyNames(proxy)、Object.getPropertySymbols(proxy)蕉陋、Object.keys(proxy)捐凭,返回一個數(shù)組,數(shù)組成員只能是字符串或者symbol寺滚,注意使用object.keys時有三種屬性會被ownkeys自動過濾(目標對象上不存在的屬性柑营、屬性名為symbol的屬性、不可遍歷的屬性)村视,如果目標對象包含不可配置屬性那么該屬性必須被ownkeys返回官套,如果目標對象是不可擴展的那么返回的數(shù)組中必須包含愿對象中的所有屬性且不能包含多余屬性。該方法返回目標對象的所有自身屬性的屬性名蚁孔,而Object,keys返回的對象僅包括目標對象自身的可遍歷屬性奶赔;getOwnPropertyDescriptor(target,propKey)攔截Object.getOwnPropertyDescriptor(proxy,prpKey),返回屬性的描述對象或者undefined;defineProperty(target,propKey,propDesc)攔截Object.defineProperty(target,propKey,propDesc)杠氢、Object.defineProperties(proxy,propDesc),返回一個布爾值站刑,如果對象不可擴展則defineProperties不能增加目標對象的屬性否則報錯,如果目標對象的屬性不可配置或不可寫那么defineProperty不可更改這個屬性鼻百;preventExtensions(target)攔截preventExtensions(target)绞旅,返回一個布爾值摆尝,只有目標對象是不可擴展的返回的才是true;getPropertyOf(target)攔截getPropertyOf(target),攔截獲取對象原型,返回一個對象或者null否則報錯因悲,如果目標對象不可擴展那么返回原型對象堕汞;isExtensible(target)攔截Object.isExtensible(proxy),返回一個布爾值,而且該方法返回的值必須和目標對象的isExtensible一致不然報錯晃琳;setPropertyOf(target,prop)攔截Object.setPropertyOf(proxy,prop), 返回一個布爾值讯检,如果目標對象是不可擴展的那么setPropertyOf方法不得改變目標對象的原型;apply(target,object,args)攔截Proxy作為實例函數(shù)調(diào)用和call卫旱、apply的操作人灼,如proxy(...args),proxy.call(object,...args),proxy.apply(....);construct(target,args)攔截Proxy實例作為構(gòu)造函數(shù)調(diào)用的操作,其實就是用于攔截new命令顾翼,construct接受兩個參數(shù)target目標對象,args構(gòu)造函數(shù)的參數(shù)對象适贸,construct方法必須返回一個對象跪呈,否則報錯。
? ? ?Proxy.revocable返回一個可取消的proxy實例取逾,它返回的是一個對象這個對象的proxy屬性是Proxy實例耗绿,revoke屬性是一個函數(shù)可以取消proxy。雖然Proxy可以代理針對目標對象的訪問砾隅,但是他不是目標對象的透明代理误阻,即不做任何攔截的情況下,也無法保證與目標對象行為一致晴埂,因為在Proxy代理的情況下目標對象內(nèi)部的this指向proxy代理究反。