JavaScript中的Reflect對象詳解_第1頁
JavaScript中的Reflect對象詳解_第2頁
JavaScript中的Reflect對象詳解_第3頁
已閱讀5頁,還剩5頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、這篇文章主要介紹了JavaScript中的Reflect對象(ES6新特性)的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下Reflect 介紹:Reflect這個(gè)對象在我的 node(v4.4.3)中還沒有實(shí)現(xiàn),babel(6.7.7)也沒有實(shí)現(xiàn),新版本的 chrome是支持的, ff比較早就支持 Proxy和Reflect 了,要讓 node支持 Reflect可以安裝 harm ony-reflect ;Reflect不是構(gòu)造函數(shù),要使用的時(shí)候直接通過Reflect.method()調(diào)用,Reflect有的方法和Proxy差不多, 而且多數(shù)Reflect方法原生的 Objec

2、t已經(jīng)重新實(shí)現(xiàn)了。什么要使用Reflect這里列舉幾個(gè)為什么要使用 Reflect的原因, 譯文地址:Reflect,大概翻譯了一遍: 1:更加有用的返回值:Reflect有一些方法和 ES5中Object方法一樣樣的,比如:Reflect.getOwnPropertyDescriptor 禾口 Reflect.defineProperty,不過,Object.defineProperty(obj, name, desc)執(zhí)行成功會(huì)返回obj,以及其它原因?qū)е碌腻e(cuò)誤,Reflect.defineProperty只會(huì)返回false或者true來表示對象的屬性是否設(shè)置上了,如下代碼可以重構(gòu):try

3、 Object.defi neProperty(obj, n ame, desc);/ property defi ned successfully catch (e) / possible failure (and might accide ntally catch the wrong excepti on)重構(gòu)成這樣:if (Reflect.defi neProperty(obj, n ame, desc) / success else / failure其余的 方法,比女口 Relect.set , Reflect.deleteProperty, Reflect.preventExten

4、sions,Reflect.setPrototypeOf,都可以進(jìn)行重構(gòu);2:函數(shù)操作,如果要判斷一個(gè)obj有定義或者繼承了屬性name,在ES5中這樣判斷:name in obj ;或者刪除一個(gè)屬性:delete objname,雖然這些很好用,很簡短,很明確,但是要使用的時(shí)候也要封裝成一個(gè)類;有了 Reflect,它幫你圭寸裝好了,Reflect.has(obj, name), Reflect.deleteProperty(obj, name);3:更加可靠的函數(shù)式執(zhí)行方式: 在ES中,要執(zhí)行一個(gè)函數(shù)f,并給它傳一組參數(shù) args, 還要綁定this的話,要這么寫:f.apply(obj,

5、 args)但是f的apply可能被重新定義成用戶自己的 apply 了,所以還是這樣寫比較靠譜:Fun cti on .prototype.apply.call(f, obj, args)上面這段代碼太長了,而且不好懂,有了 Reflect,我們可以更短更簡潔明了:Reflect.apply(f, obj, args)你想通過不確定長度的參數(shù)實(shí)例化一個(gè)構(gòu)可以這么寫:4:可變參數(shù)形式的構(gòu)造函數(shù):想象一下,造函數(shù),在ES5中,我們可以使用擴(kuò)展符號(hào),所以,我們只能用F.apply,或者F.call的方式傳 這個(gè)就坑爹了,不過有了 Reflect, var obj = new F(.arg

6、s)不過在ES5中,不支持?jǐn)U展符啊,不同的參數(shù), 可惜F是一個(gè)構(gòu)造函數(shù),我們在ES5中能夠這么寫:var obj = Reflect.c on struct(F, args)5:控制訪問器或者讀取器的this :在ES5中,想要讀取一個(gè)元素的屬性或者設(shè)置屬性要這樣:var n ame = . / get property n ame as a stri ngobjn ame / gen eric property lookupobjn ame = value / gen eric propertyupdateReflect.get和Reflect.set方法允許我們做同樣的事情,而且他增加了一

7、個(gè)額外的參數(shù)reciver,允許我們設(shè)置對象的setter和getter的上下this:var n ame = . / get property n ame as a stri ngReflect.get(obj, name, wrapper) / if objname is an accessor, it gets run with this = wrapperReflect.set(obj, name, value, wrapper)訪問器中不想使用自己的方法,而是想要重定向this至U wrapper:var obj = set foo(value) retur n this.bar()

8、; ,bar: function。alert(1);;var wrapper = bar : function。con sole .lo g(wrapper);Reflect.set(obj, foo, value, wrapper);6:避免直接訪問_proto_ :ES5提供了 Object.getPrototypeOf(obj),去訪問對象的原型,ES6提供也提供了Reflect.getPrototypeOf(obj)和 Reflect.setPrototypeOf(obj, newProto),這個(gè)是新的方法 去訪問和設(shè)置對象的原型:Reflect.apply 的使用Reflect.a

9、pply 其實(shí)就是 ES5 中的 Ftotype.apply() 替身,執(zhí)行 Reflect.apply 需 要三個(gè)參數(shù)第一個(gè)參數(shù)為:需要執(zhí)行的函數(shù);第二個(gè)參數(shù)為:需要執(zhí)行函數(shù)的上下文this;第三個(gè)參數(shù)為:是一個(gè)數(shù)組或者偽數(shù)組,會(huì)作為執(zhí)行函數(shù)的參數(shù);& t;script>let fn = fun cti on() this.attr = 0,1,2,3;;let obj = ;Reflect. apply(fn, obj,)con sole .lo g(obj);&n bsp;& lt;/script >Reflect.apply 的 DEMO :& t;s

10、cript>Reflect. apply(Math.floor, un defi ned, 1.75); / 輸出:1;Reflect. apply(Stri ng.fromCharCode, un defi ned, 104, 101, 108, 108, 111); / 輸出:helloReflect.apply(RegEtotype.exec, /ab/, c on fabulati on ).i ndex; /輸出: 4Reflect.apply(.charAt, pon ies, 3); / 輸出:i</script>Reflect 可以與 Proxy

11、聯(lián)合使用:var Fn = function();Fn. prototype.r un = fun cti on() con sole .lo g( r uns out);var Proxy Fn = new Proxy( Fn, con struct (target ,arugme nts) con sole .lo g(proxy con structor);var obj = new target(.arugme nts);/Reflect.apply 的使用方法;Reflect.apply(totype.r un, obj, arugme nts);return o

12、bj;);new ProxyFn (); / 會(huì)先輸出:proxy constructor; 再輸出:runs outReflect.construct()的使用:Reflect.construct其實(shí)就是實(shí)例化構(gòu)造函數(shù),通過傳參形式的實(shí)現(xiàn),執(zhí)行的方式不同,效果其實(shí)一樣,con struct的第一個(gè)參數(shù)為構(gòu)造函數(shù),第二個(gè)參數(shù)由參數(shù)組成的數(shù)組或者偽數(shù)組,基本的使用方法為:var Fn = function( arg) this.args = arg;con sole.log( new Fn (1), Reflect.co nstruct(F n,1) ); /輸出是一樣的var d = Refl

13、ect.co nstruct(Date, 1776, 6, 4);d in sta nceof Date; / trued.getFullYear(); / 1776/所以Reflect.consturct和new 構(gòu)所以Reflect.consturct和new 構(gòu)造函數(shù)是一樣,至少到目前為止.我們可以給Reflect.construct傳第三個(gè)參數(shù),第三個(gè)參數(shù)為一個(gè)超類,新元素會(huì)繼承這個(gè)超類;& t;script>function someC on structor() var result = Reflect.c on struct(Array, , someC on struct

14、or);Reflect.getPrototypeOf(result); / someC on totypeArray.isArray(result); / true/orvar Fn = function。this.attr = 1;var Pers on = fun ctio n() ;Pers on. prototype.r un = fun cti on() ;con sole .log( Reflect.c on struct (Fn, , Pers on);& lt;/script >所以我們可以用這個(gè)實(shí)現(xiàn)一個(gè)特殊的的數(shù)組,繼承數(shù)組,但是也有自己的方法;

15、var Fn = function。Array.apply(this, argume nts);this.shot = ()=> con sole .lo g(heheda);var arr = Reflect.construct(Fn, )Reflect.defineProperty的使用;Reflect.defineProperty返回的是一個(gè)布爾值,通過直接賦值的方式把屬性和屬性值添加給對象返回的是一整個(gè)對象,如果添加失敗會(huì)拋錯(cuò);var obj = ;obj.x = 10;console.log(obj.x) / 輸出:10;使用 Reflect.defineProperty 的方

16、式添加值;& t;script>var obj = ;if( Reflect.defi neProperty(obj, x, value : 7 ) ) con sole .lo g(added success);elseconsole.log(添加失敗);</script>如果我們執(zhí)行 preventExtensions,通過 Object.defindProperty 定義新屬性報(bào)錯(cuò)了,但是通過Reflect.defineProperty沒有報(bào)錯(cuò),返回了一個(gè)false的值:var obj = ;Object.preve ntExte nsio ns(obj);Object

17、.defi neProperty(obj, x , value: 101,writable: false,enu merable: false,con figurable: false);/直接拋錯(cuò)了 ;console.log( Reflect.defineProperty(obj, x, value:101) ) / 返回 false:如果通過直接賦值的方式,無論是否正確賦值,都返回設(shè)置的值,除非我們手動(dòng)確認(rèn)對象的屬性值是否設(shè)置成功;& t;script>var obj = ;Object.preve ntExte nsio ns(obj);con sole .log( obj.aa

18、= 1 ); / 輸出:1 ;con sole .lo g(obj.aa) / 輸出:un defi ned ;</script >Reflect.deleteProperty的使用:Reflect.deleteProperty 和 Reflect.defineProperty 的使用方法差不多,Reflect.deleteProperty和delete obj.xx的操作結(jié)果是一樣,區(qū)別是使用形式不同:一個(gè)是操作符,一個(gè)是函數(shù)調(diào)用;Reflect.deleteProperty(Object.freeze(foo: 1), foo); / falsedelete Object.fr

19、eeze(foo: 1).foo; / 輸出:false ; Reflect.get()方法的使用這個(gè)方法的有兩個(gè)必須的參數(shù):第一個(gè)為obj目標(biāo)對象,第二個(gè)為屬性名對象,第三個(gè)是可選的,是作為讀取器的上下文(this);var obj = ;obj.foo = 1;console.log( obj.foo ); / 輸出:1;console.log( Reflect.get(obj, foo) ) / 輸出:1;如果 Reflect.get 有第三個(gè)參數(shù)的話,第三個(gè) 參數(shù)會(huì)作為讀取器的上下文:var Reflect = require(harm on y-reflect);var obj =

20、foo : 1,get bar() return this.foo;var foo = ;foo.foo = heheda;con sole .lo g(Reflect.get(obj, bar, foo);Reflect.getOwnPropertyDescritptor()方法的使用:通過 Reflect.getOwnPropertyDescritptor 獲取屬性描述:Reflect.getOw nPropertyDescriptor(x: hello, x);也可以這樣獲?。篛bject.getOw nPropertyDescriptor(x:1,x);/這兩個(gè)的區(qū)別是一個(gè)會(huì)包裝對象,

21、一個(gè)不會(huì):Reflect.getOw nPropertyDescriptor(hello,0); / 拋出異常Object.getOwnPropertyDescriptor(hello,0); / 輸出: value: h, writable: false, enu merable: true, con figurable: falseReflect.getPrototypeOf() 方法的使用:Reflect.getPrototypeOf和Object.getPrototypeOf是一樣的,他們都是返回一個(gè)對象的原型 Reflect.getPrototypeOf(); / 輸出:Object

22、.prototypeReflect.getPrototypeOf(Ototype); / 輸出:null Reflect.getPrototypeOf(Object.create(null); / 輸出:nullReflect.has 的使用 Reflect.has這個(gè)方法有點(diǎn)像操作符:in ,比如這樣:xx in obj;& t;script>Reflect.has(x:O, x) / 輸出:true;Reflect.has(y:O, y) / 輸出:true; var obj = x:0; con sole .log( x in obj); var proxy =

23、new Proxy(obj, has : function (target, args) con sole .lo g(執(zhí)行 has 方法);return Reflect.has(target,.args); ); con sole .log( x in proxy); 輸出:true ; con sole .lo g(Reflect.has(proxy, x) 輸出:true ; </script>這個(gè)demo的obj相當(dāng)于變成了一個(gè)方法了,沒他什么用,只是利用了他的has方法:obj = new Proxy(, has(t, k) return k.startsWith(doo

24、r); );Reflect.has(obj, doorbell); / trueReflect.has(obj, dormitory); / falseReflect.isExtensible()的使用/現(xiàn)在這個(gè)元素是可以擴(kuò)展的;var empty = ;Reflect.isExte nsible(empty); / = trueII使用preventExtensions方法,讓這個(gè)對象無法擴(kuò)展新屬性;Reflect.preve ntExte nsio ns(empty);Reflect.isExte nsible(empty); II = falseII這個(gè)對象無法擴(kuò)展新屬性,可寫的屬性依然

25、可以改動(dòng)var sealed = Object.seal();Reflect.isExte nsible(sealed); II = falseII這個(gè)對象完全被凍結(jié)了var froze n = Object.freeze();Reflect.isExtensible(frozen); II = falseReflect.isExtensible 禾口 Object.isExtensible 的區(qū)另U 是,如果參數(shù)不對,一個(gè)會(huì)拋錯(cuò),另一個(gè)只是返回true或者false:Reflect.isExte nsible(1);II 拋錯(cuò)了 : 1 is not an objectObject.isEx

26、te nsible(1);II 返回 false;Reflect.ownKeys()方法的使用:Reflect.ownKeys , Object 可沒有 own Keys 方法,Reflect.ownKeysz 他的作用是返回對象 的 keys;console.log(Reflect.ownKeys(a:0,b:1,c:2,d:3); II輸出:a, b, c, dcon sole.log(Reflect.ow nKeys(); II le ngthvar sym = Symbol.for(comet);var sym2 = Symbol.for(meteor);var obj = sym:

27、0, str: 0, 773: 0, 0: 0,sym2: 0, -1: 0, 8: 0, seco nd str: 0;Reflect.ownKeys(obj); II 輸出:I 0, 8, 773, str, -1, second str, Symbol(comet), Symbol(meteor) Reflect.ownKeys的排序是根據(jù):先顯示數(shù)字,數(shù)字根據(jù)大小排序,然后是出現(xiàn)這中排序是因?yàn)?,你給一個(gè)對象屬性賦值時(shí)候,對象的key的排序規(guī)則就是先數(shù)字,在字符串,最后是symbol類型的數(shù)據(jù);Reflect.preventExtensions()的使用方法:Object 也有 prev

28、entExtensions 方法,禾口 Reflect.preventExtensions()有一點(diǎn)區(qū)另U,女口果Reflect.preventExtensions參數(shù)不是對象會(huì)拋錯(cuò);var empty = ;Reflect.isExte nsible(empty); / = true/執(zhí)行preventExtensions后的對象可以修改;Reflect.preve ntExte nsio ns(empty);Reflect.isExte nsible(empty); / = falseReflect.preve ntExte nsio ns(1);/ TypeError: 1 is not an objectObject.preve ntExte nsio ns(1);/不會(huì)拋錯(cuò),會(huì)返回:1Reflect.set()Reflect.set方法和get是差不多的;var obj = ;Reflect.set(obj, prop, value); / 輸出:truecon sole .log( p ); / 輸出:valuevar arr = duck, duck, duck;Reflect.set(arr, 2, goose); / truecon sole .log( arr2 ); / gooseReflect.set(arr, len gth, 1)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論