JavaScript中的Reflect对象详解

上传人:jin****ng 文档编号:79261184 上传时间:2022-04-23 格式:DOC 页数:10 大小:66.50KB
返回 下载 相关 举报
JavaScript中的Reflect对象详解_第1页
第1页 / 共10页
JavaScript中的Reflect对象详解_第2页
第2页 / 共10页
JavaScript中的Reflect对象详解_第3页
第3页 / 共10页
亲,该文档总共10页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
这篇文章主要介绍了JavaScript中的Reflect对象(ES6新特性)的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下Reflect 介绍:Reflect这个对象在我的 node(v4.4.3)中还没有实现,babel(6.7.7)也没有实现,新版本的 chrome是支持的, ff比较早就支持 Proxy和Reflect 了,要让 node支持 Reflect可以安装 harm ony-reflect ;Reflect不是构造函数,要使用的时候直接通过Reflect.method()调用,Reflect有的方法和Proxy差不多, 而且多数Reflect方法原生的 Object已经重新实现了。什么要使用Reflect这里列举几个为什么要使用 Reflect的原因, 译文地址:Reflect,大概翻译了一遍: 1:更加有用的返回值:Reflect有一些方法和 ES5中Object方法一样样的,比如:Reflect.getOwnPropertyDescriptor 禾口 Reflect.defineProperty,不过,Object.defineProperty(obj, name, desc)执行成功会返回obj,以及其它原因导致的错误,Reflect.defineProperty只会返回false或者true来表示对象的属性是否设置上了,如下代码可以重构:try Object.defi neProperty(obj, n ame, desc);/ property defi ned successfully catch (e) / possible failure (and might accide ntally catch the wrong excepti on)重构成这样:if (Reflect.defi neProperty(obj, n ame, desc) / success else / failure其余的 方法,比女口 Relect.set , Reflect.deleteProperty, Reflect.preventExtensions,Reflect.setPrototypeOf,都可以进行重构;2:函数操作,如果要判断一个obj有定义或者继承了属性name,在ES5中这样判断:name in obj ;或者删除一个属性:delete objname,虽然这些很好用,很简短,很明确,但是要使用的时候也要封装成一个类;有了 Reflect,它帮你圭寸装好了,Reflect.has(obj, name), Reflect.deleteProperty(obj, name);3:更加可靠的函数式执行方式: 在ES中,要执行一个函数f,并给它传一组参数 args, 还要绑定this的话,要这么写:f.apply(obj, args)但是f的apply可能被重新定义成用户自己的 apply 了,所以还是这样写比较靠谱:Fun cti on .prototype.apply.call(f, obj, args)上面这段代码太长了,而且不好懂,有了 Reflect,我们可以更短更简洁明了:Reflect.apply(f, obj, args)你想通过不确定长度的参数实例化一个构可以这么写:4:可变参数形式的构造函数:想象一下,造函数,在ES5中,我们可以使用扩展符号,所以,我们只能用F.apply,或者F.call的方式传 这个就坑爹了,不过有了 Reflect, var obj = new F(.args)不过在ES5中,不支持扩展符啊,不同的参数, 可惜F是一个构造函数,我们在ES5中能够这么写:var obj = Reflect.c on struct(F, args)5:控制访问器或者读取器的this :在ES5中,想要读取一个元素的属性或者设置属性要这样:var n ame = . / get property n ame as a stri ngobjn ame / gen eric property lookupobjn ame = value / gen eric propertyupdateReflect.get和Reflect.set方法允许我们做同样的事情,而且他增加了一个额外的参数reciver,允许我们设置对象的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(); ,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),这个是新的方法 去访问和设置对象的原型:Reflect.apply 的使用Reflect.apply 其实就是 ES5 中的 Function.prototype.apply() 替身,执行 Reflect.apply 需 要三个参数第一个参数为:需要执行的函数;第二个参数为:需要执行函数的上下文this;第三个参数为:是一个数组或者伪数组,会作为执行函数的参数;& 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;script>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(RegExp.prototype.exec, /ab/, c on fabulati on ).i ndex; /输出: 4Reflect.apply(.charAt, pon ies, 3); / 输出:i</script>Reflect 可以与 Proxy 联合使用: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(target.prototype.r un, obj, arugme nts);return obj;);new ProxyFn (); / 会先输出:proxy constructor; 再输出:runs outReflect.construct()的使用:Reflect.construct其实就是实例化构造函数,通过传参形式的实现,执行的方式不同,效果其实一样,con struct的第一个参数为构造函数,第二个参数由参数组成的数组或者伪数组,基本的使用方法为:var Fn = function( arg) this.args = arg;con sole.log( new Fn (1), Reflect.co nstruct(F n,1) ); /输出是一样的var d = Reflect.co nstruct(Date, 1776, 6, 4);d in sta nceof Date; / trued.getFullYear(); / 1776/所以Reflect.consturct和new 构所以Reflect.consturct和new 构造函数是一样,至少到目前为止.我们可以给Reflect.construct传第三个参数,第三个参数为一个超类,新元素会继承这个超类;& t;script>function someC on structor() var result = Reflect.c on struct(Array, , someC on structor);Reflect.getPrototypeOf(result); / someC on structor.prototypeArray.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 >所以我们可以用这个实现一个特殊的的数组,继承数组,但是也有自己的方法;var Fn = function。Array.apply(this, argume nts);this.shot = ()=> con sole .lo g(heheda);var arr = Reflect.construct(Fn, )Reflect.defineProperty的使用;Reflect.defineProperty返回的是一个布尔值,通过直接赋值的方式把属性和属性值添加给对象返回的是一整个对象,如果添加失败会抛错;var obj = ;obj.x = 10;console.log(obj.x) / 输出:10;使用 Reflect.defineProperty 的方式添加值;& t;script>var obj = ;if( Reflect.defi neProperty(obj, x, value : 7 ) ) con sole .lo g(added success);elseconsole.log(添加失败);</script>如果我们执行 preventExtensions,通过 Object.defindProperty 定义新属性报错了,但是通过Reflect.defineProperty没有报错,返回了一个false的值:var obj = ;Object.preve ntExte nsio ns(obj);Object.defi neProperty(obj, x , value: 101,writable: false,enu merable: false,con figurable: false);/直接抛错了 ;console.log( Reflect.defineProperty(obj, x, value:101) ) / 返回 false:如果通过直接赋值的方式,无论是否正确赋值,都返回设置的值,除非我们手动确认对象的属性值是否设置成功;& t;script>var obj = ;Object.preve ntExte nsio ns(obj);con sole .log( obj.aa = 1 ); / 输出:1 ;con sole .lo g(obj.aa) / 输出:un defi ned ;</script >Reflect.deleteProperty的使用:Reflect.deleteProperty 和 Reflect.defineProperty 的使用方法差不多,Reflect.deleteProperty和delete obj.xx的操作结果是一样,区别是使用形式不同:一个是操作符,一个是函数调用;Reflect.deleteProperty(Object.freeze(foo: 1), foo); / falsedelete Object.freeze(foo: 1).foo; / 输出:false ; Reflect.get()方法的使用这个方法的有两个必须的参数:第一个为obj目标对象,第二个为属性名对象,第三个是可选的,是作为读取器的上下文(this);var obj = ;obj.foo = 1;console.log( obj.foo ); / 输出:1;console.log( Reflect.get(obj, foo) ) / 输出:1;如果 Reflect.get 有第三个参数的话,第三个 参数会作为读取器的上下文:var Reflect = require(harm on y-reflect);var obj = 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);也可以这样获取:Object.getOw nPropertyDescriptor(x:1,x);/这两个的区别是一个会包装对象,一个不会:Reflect.getOw nPropertyDescriptor(hello,0); / 抛出异常Object.getOwnPropertyDescriptor(hello,0); / 输出: value: h, writable: false, enu merable: true, con figurable: falseReflect.getPrototypeOf() 方法的使用:Reflect.getPrototypeOf和Object.getPrototypeOf是一样的,他们都是返回一个对象的原型 Reflect.getPrototypeOf(); / 输出:Object.prototypeReflect.getPrototypeOf(Object.prototype); / 输出:null Reflect.getPrototypeOf(Object.create(null); / 输出:nullReflect.has 的使用 Reflect.has这个方法有点像操作符: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 = new Proxy(obj, has : function (target, args) con sole .lo g(执行 has 方法);return Reflect.has(target,.args); ); con sole .log( x in proxy); 输出:true ; con sole .lo g(Reflect.has(proxy, x) 输出:true ; </script>这个demo的obj相当于变成了一个方法了,没他什么用,只是利用了他的has方法:obj = new Proxy(, has(t, k) return k.startsWith(door); );Reflect.has(obj, doorbell); / trueReflect.has(obj, dormitory); / falseReflect.isExtensible()的使用/现在这个元素是可以扩展的;var empty = ;Reflect.isExte nsible(empty); / = trueII使用preventExtensions方法,让这个对象无法扩展新属性;Reflect.preve ntExte nsio ns(empty);Reflect.isExte nsible(empty); II = falseII这个对象无法扩展新属性,可写的属性依然可以改动var sealed = Object.seal();Reflect.isExte nsible(sealed); II = falseII这个对象完全被冻结了var froze n = Object.freeze();Reflect.isExtensible(frozen); II = falseReflect.isExtensible 禾口 Object.isExtensible 的区另U 是,如果参数不对,一个会抛错,另一个只是返回true或者false:Reflect.isExte nsible(1);II 抛错了 : 1 is not an objectObject.isExte 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: 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的排序是根据:先显示数字,数字根据大小排序,然后是出现这中排序是因为,你给一个对象属性赋值时候,对象的key的排序规则就是先数字,在字符串,最后是symbol类型的数据;Reflect.preventExtensions()的使用方法:Object 也有 preventExtensions 方法,禾口 Reflect.preventExtensions()有一点区另U,女口果Reflect.preventExtensions参数不是对象会抛错;var empty = ;Reflect.isExte nsible(empty); / = true/执行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);/不会抛错,会返回:1Reflect.set()Reflect.set方法和get是差不多的;var obj = ;Reflect.set(obj, prop, value); / 输出:truecon sole .log( obj.prop ); / 输出:valuevar arr = duck, duck, duck;Reflect.set(arr, 2, goose); / truecon sole .log( arr2 ); / gooseReflect.set(arr, len gth, 1); / truecon sole .log( arr );/ duck;Reflect.set(obj) 相当于 Reflect.set(obj, un defi ned, un defi ned); var obj = ;Reflect.set(obj); / 输出:true/ 以上的代码相当于Reflect.set(obj, un defi ned, un defi ned);Reflect.getOw nPropertyDescriptor(obj, un defi ned);/ value: un defi ned, writable: true, enu merable: true, con figurable: true Reflect.set 也可以 有第四个参数,这个参数会作为stter的this;var obj = value : 10,set key( value ) con sole .lo g(setter);this.value = value;,get key() return this.value;Reflect.set(obj,key,heheda, obj);con sole .lo g(obj);Reflect.setPrototypeOf()Reflect.setPrototypeOf()方法和Object.setPrototypeOf差不多一样样的,会给对象设置原型,就是更改对象的 _proto_属性了;Reflect.setPrototypeOf(, Object.prototype); / 输出 true /给该对象数组Prototype为null.Reflect.setPrototypeOf(, null); / true/ 此时的 obj._proto_ 为 undefine/把对象冻结以后重新设置 prototypeReflect.setPrototypeOf(Object.freeze(), null); / false/如果原型链循环依赖的话就会返回false.var target = ;var proto = Object.create(target);Reflect.setPrototypeOf(target, proto); / false
展开阅读全文
相关资源
相关搜索

最新文档


当前位置:首页 > 办公文档 > 活动策划


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!