摘要:與學(xué)習(xí)的新語法糖既能學(xué)習(xí)到新東西,又能使得自己的代碼更加優(yōu)雅,逼格更高,爽與之間的運(yùn)用就是對對象的操作觸發(fā)的攔截是對對象進(jìn)行代理,通過生成的對象間接操作原本對象,最常見的就是與語法形式是需要操作的對象,而是包含操作對象的一些方法的對象是能夠
Proxy與Reflect
學(xué)習(xí)es6的新語法糖既能學(xué)習(xí)到新東西,又能使得自己的代碼更加優(yōu)雅,逼格更高,爽
proxy與Reflect之間的運(yùn)用就是Reflect對對象的操作觸發(fā)Proxy的攔截
Proxy是對對象進(jìn)行代理,通過proxy生成的對象間接操作原本對象,最常見的就是get與set;語法形式var proxy = new Proxy(target, handler); target是需要操作的對象,而handler是包含操作target對象的一些方法的對象
Reflect是能夠更加優(yōu)雅的使用Object的相關(guān)方法
學(xué)習(xí)APIget
proxy: get(target, propKey, receiver)=>依次為目標(biāo)對象、屬性名和 proxy 實(shí)例本身(嚴(yán)格地說,是操作行為所針對的對象),其中最后一個(gè)參數(shù)可選。
let obj = { a: "foo", b: "Proxy", foo: "" } let proxy = new Proxy(obj, { get (target, proKey, receive) { console.log(target === obj) //true return "當(dāng)對proxy進(jìn)行取值操作時(shí)會(huì)觸發(fā)這個(gè)get函數(shù)" } })
ps:proxy對target進(jìn)行了代理,target就是obj對象,receive用于規(guī)定this到底指向哪個(gè)對象,
proxy.foo //當(dāng)對proxy進(jìn)行取值操作時(shí)會(huì)觸發(fā)這個(gè)get函數(shù)
上面這種情況并沒有改變this的,所以console.log(receive === proxy) //true
Reflect也有g(shù)et方法:Reflect.get(target, prokey, receive)
Reflect.get(proxy, "foo") //同上沒有this的指向
let newobj = { foo: "this指向?qū)⒏淖? } Reflect.get(proxy, "foo", newobj) //foo = console.log(receive === proxy) //true
所以對Reflect.get的第三個(gè)參數(shù)進(jìn)行賦值將帶入帶proxy的get的第三個(gè)參數(shù)中
set
與get類似,這個(gè)是賦值時(shí)會(huì)觸發(fā)set方法
proxy: set(target, propKey, value, receiver)
let obj = {} let newobj = { a: "123" } let proxy = new Proxy(obj, { set (target, proKey, value, receive) { return target[proKey] = `當(dāng)對proxy進(jìn)行賦值操作時(shí)會(huì)觸發(fā)這個(gè)set函數(shù)${value}` } }) proxy.a = 666 //receive === proxy true Reflect.set(proxy, "a", 888) //receive === proxy true Reflect.set(proxy, "a", 888, newobj) //receive === newobj true
apply
proxy的apply:apply(target, object, args)
let twice = { apply (target, ctx, args) { console.log(ctx) //undefined return Reflect.apply(...arguments); } } function sum (left, right) { this.num = 888 /如果ctx沒有傳入或者傳入null,則會(huì)進(jìn)行window.num = 888的賦值 return left + right + this.nm } let obj = { nm: 666 } var proxy = new Proxy(sum, twice); console.log(proxy(1, 2)) // 6 console.log(proxy.apply(obj, [7, 8])) //ctx則為obj,并改變r(jià)eturn
執(zhí)行流程:proxy觸發(fā)函數(shù)調(diào)用,執(zhí)行apply的方法,將參數(shù)自動(dòng)帶入,target就是sum函數(shù),ctx沒有傳入為undefined,args為1, 2,接下來將全部參數(shù)帶入執(zhí)行Reflect.apply
has
has比較簡單,是對對象進(jìn)行in運(yùn)算,判斷該屬性是否存在對象中,可以是自身也可以是原型鏈上,不管是否可遍歷
construct
在構(gòu)造函數(shù)new時(shí)觸發(fā),
var p = new Proxy(function () {}, { construct: function(target, args, newTarget) { console.log("called: " + args.join(", ")); console.log(newTarget === p) return { value: args[0] * 10 }; } }); console.log((new p(1)).value) //等價(jià)于下面,Reflect.construct(target, args), args必須是數(shù)組 console.log(Reflect.construct(p, [1]))
ownKeys
返回對象中自身的所有屬性,當(dāng)然具體還是取決于return 什么內(nèi)容;
觸發(fā)條件: Object.getOwnPropertyNames() Object.getOwnPropertySymbols() Object.keys() for...in循環(huán)
let target = { a: 1, b: 2, c: 3, [Symbol.for("secret")]: "4", }; Object.defineProperty(target, "key", { enumerable: false, configurable: true, writable: true, value: "static" }); let handler = { ownKeys(target) { return ["a", "d", Symbol.for("secret"), "key"]; } }; let proxy = new Proxy(target, handler); console.log(Object.keys(proxy)) //自動(dòng)過濾symbol,不存在的屬性,不可遍歷的屬性 console.log(Reflect.ownKeys(proxy)) //返回handler中return的值
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/100585.html
摘要:理解元編程和是屬于元編程范疇的,能介入的對象底層操作進(jìn)行的過程中,并加以影響。元編程中的元的概念可以理解為程序本身。中,便是兩個(gè)可以用來進(jìn)行元編程的特性。在之后,標(biāo)準(zhǔn)引入了,從而提供比較完善的元編程能力。 導(dǎo)讀 幾年前 ES6 剛出來的時(shí)候接觸過 元編程(Metaprogramming)的概念,不過當(dāng)時(shí)還沒有深究。今天在應(yīng)用和學(xué)習(xí)中不斷接觸到這概念,比如 mobx 5 中就用到了 Pr...
摘要:返回一個(gè)布爾值攔截操作符,返回一個(gè)布爾值攔截操作符,返回一個(gè)布爾值攔截遍歷器,返回一個(gè)遍歷器攔截,返回一個(gè)布爾值攔截,返回一個(gè)數(shù)組。 Proxy 對象 Proxy 用來修改某些默認(rèn)操作,等同于在語言層面做出修改。所以屬于一種元編程(meta programming), 即對編程語言進(jìn)行編程。字面理解為Proxy代理了某些默認(rèn)的操作。其使用格式如下: var proxy = new Pr...
摘要:此時(shí),鏈家起到的作用就是代理的作用。驗(yàn)證代理構(gòu)造函數(shù)第二個(gè)參數(shù)中的方法,可以很方便的驗(yàn)證向一個(gè)對象的傳值。 1 什么是代理模式 showImg(https://segmentfault.com/img/remote/1460000015800706?w=1262&h=464); 為其他對象提供一種代理以控制對這個(gè)對象的訪問。在某些情況下,一個(gè)對象不適合或者不能直接引用另一個(gè)對象,而代理...
摘要:將轉(zhuǎn)換成常見的使用實(shí)現(xiàn)的基于迭代器的迭代。處停止迭代器基于鴨子模型接口這里使用語法僅僅為了說明問題使用支持為了使用迭代器屬性需要引入。生成器是迭代器的子類,包含了附加的與。 原文地址:http://babeljs.io/docs/learn-...本文基于Luke Hoban精妙的文章《es6features》,請把star獻(xiàn)給他,你可以在此嘗試這些特性REPL。 概述 ECMAScr...
摘要:凡是部署了屬性的數(shù)據(jù)結(jié)構(gòu),就稱為部署了遍歷器接口。調(diào)用這個(gè)接口,就會(huì)返回一個(gè)遍歷器對象。 ES6在2015年6月就得以批準(zhǔn),至今已兩年了。近一年多以來陸續(xù)看過很多ES6的資料,工作項(xiàng)目中也逐步的用上了很多ES6的特性(let,const,promise,Template strings,Class,箭頭函數(shù)等等),不得不說,這些特性給開發(fā)帶來了非常多的便利。但是做決定我的ES6知識其...
閱讀 2118·2021-11-18 10:02
閱讀 2865·2021-09-04 16:41
閱讀 1159·2019-08-30 15:55
閱讀 1421·2019-08-29 17:27
閱讀 1119·2019-08-29 17:12
閱讀 2542·2019-08-29 15:38
閱讀 2867·2019-08-29 13:02
閱讀 2843·2019-08-29 12:29