当前位置: 首页 > Web前端 > vue.js

详解Reflect:Reflect和Object的异同,Reflect的一些内置方法以及方法注意点

时间:2023-03-31 22:23:44 vue.js

Reflect详解:Reflect与Object的异同、Reflect的一些内置方法及方法注意点已有的方法也可以通过Reflect访问。单以Reflect为例,可以理解为Reflect继承了Object的一些内置方法,在Object对象上提供了一些方法优化的缺陷,例如:在Object.当该属性用于getter或setter时将抛出错误。对于这个错误,我们需要用trycatch来捕捉,Reflect.defineProperty会抛出false表示这次操作失败(Reflect会针对对象的操作抛出true和false来表示操作是否成功)。Objectconstobj={name:'东方无敌'}Object.defineProperty(obj,'age',{value:100,writable:true,//只读configurable:false//不可删除修改})Object.defineProperty(obj,'age',{get(){return200}})console.log(obj.age);//TypeError:Cannotredefineproperty:age//错误,无法重新定义属性Reflectconstobj2={name:'WesternDefeat'}Object.defineProperty(obj2,'age',{value:100,writable:true,//read-onlyconfigurable:false//不能被删除和修改})letstatus=Reflect.defineProperty(obj2,'age',{get(){return}})console.log(status);//falseconsole.log(obj2.age);//100//Reflect会抛出false表示操作失败部分操作Object是命令式letobj3={name:'东方无敌',age:100}console.log('name'inobj3);//trueconsole.log(删除obj3.age);//trueconsole.log(obj3);//{name:'东方不败'}并且Reflect的操作是函数式的letobj4={name:'西方不败',age:100}console.log(Reflect.has(obj4,'name'));//trueconsole.log(Reflect.deleteProperty(obj4,'age'));//trueconsole.log(obj4);//{姓名:'从上面的案例我们可以知道,Object内部的一些方法是可以在Reflect上访问的,Reflect对象有13个静态方法,如下:1.Reflect.apply(target,thisArg,args)2.Reflect。construct(target,args)3,Reflect.get(target,name,receiver)4,Reflect.set(target,name,value,receiver)5,Reflect.defineProperty(target,name,desc)6,Reflect.deleteProperty(目标,名称)7,Reflect.has(目标,名称)8,Reflect.ownKeys(目标)9,Reflect.isExtensible(目标)10,Reflect.preventExtensions(目标)11,Reflect.getOwnPropertyDescriptor(目标,名称)12,Reflect.getPrototypeOf(target)13.Reflect.setPrototypeOf(target,prototype)下面是对上面一些方法的使用的解释Reflect.get(target,name,receiver)Relect.get()有三个参数,分别是1、`target`:目标对象2、`name`:对象属性3、`receiver`:代理对象(可忽略)功能:查找并返回目标对象的name属性,如果该属性不存在则返回undefinedleto={name:'Orient',text:'undefeated'}console.log(Reflect.get(o,'name'));//东方Reflect.set(target,name,value,receiver)用于设置目标对象的name属性等于value,修改成功返回true,失败返回falseleto2={name:'IntroductiontoArt',}//如果设置为不可修改,那么back会输出false和price的值那么它是未定义的//Object.defineProperty(o2,'price',{//configurable:false//})letback=Reflect.set(o2,'price',100)console.log(back);//真console.log(o2);//{name:'IntroductiontoArt',price:100}Reflect.has(obj,name)相当于Object中的in运算符,判断当前属性是否存在于目标对象中,true存在,false不存在existleto3={name:'中国工艺美术史'}console.log('name'ino3);//trueconsole.log(Reflect.has(o3,'name'));//trueif如果Reflect.has的第一个参数不是对象,会报错。Reflect.deleteProperty(obj,name)相当于Object的删除操作:deleteobj.name,用于删除对象的属性。leto4={book:'FightingGrass',text:'Ahelpinghand'}//Objectdeleteo4.bookconsole.log(o4);//{text:'Ahelpinghand'}//ReflectReflect.deleteProperty(o4,'text')console.log(o4);//{}Reflect.construct(target,args)相当于newclass(params),这里Reflect不能用new创建方法调用构造函数Person(name){this.name=name}//new写法letonNew=newPerson('Orient')//Reflect.constructletonNew2=Reflect.construct(Person,['Undefeated'])Reflect.construct的第一个参数不是函数,会报错。Reflect.getPrototypeOf(obj)对应Object.getPrototypeOf(obj),用于读取对象的__proto__属性leto5=newString()//Object.getPrototypeOf()console.log(Object.getPrototypeOf(o5)==String.prototype);//true//Reflect.getPrototypeOf()console.log(Reflect.getPrototypeOf(o5)==String.prototype);//trueReflect.setPrototypeOf(obj,newProto)对应Object.setPrototypeOf(obj,newProto),用于设置目标对象的原型(prototype)leto6={}Reflect.setPrototypeOf(o6,Array.prototype)控制台日志(o6.length);//0Reflect.defineProperty(target,propertyKey,attributes)等同于Object.defineProperty,Reflect.defineProperty()用于定义对象的属性leto7={name:'东方无敌'}Reflect.defineProperty(o7,'age',{value:100,configurable:true,enumerable:true,writable:true})console.log(o7);//{name:'东方无敌',age:100}如果Reflect.defineProperty()的第一个参数不是对象,会报错。Reflect.getOwnPropertyDescriptor(target,propertyKey)对应Object.getOwnPropertyDescriptor,用于获取指定属性的描述对象leto8={name:'东方无敌'}Reflect.defineProperty(o8,'age',{value:100,可配置:真,可枚举:真,可写:真})letback8=Reflect.getOwnPropertyDescriptor(o8,'age')console.log(back8);//{value:100,writable:true,enumerable:true,configurable:true}如果Reflect.getOwnPropertyDescriptor()的第一个参数不是对象,则会抛出错误。Reflect.isExtensible(target)等同于Object.isExtensible,返回一个布尔值,表示当前对象是否被扩展leto9={}letback9=Reflect.isExtensible(o9)console.log(back9);//trueiftheparameterisnotanobject报错,非对象本质上是不可扩展的console.log(Reflect.isExtensible(100));//报错Reflect.preventExtensions(target)等价于Object.preventExtensions,可以让目标对象不可扩展,返回一个布尔值是否设置成功letb={}letinfo=Reflect.preventExtensions(b)控制台日志(信息);//trueconsole.log(Reflect.isExtensible(b));//false如果参数不是对象,会报错Reflect.ownKeys(target)用于返回目标对象的所有属性,包括Symbolletaddress=Symbol.for('Wuhan')letb2={name:'东方无敌',age:100,[address]:'世界城广场'}letinfo2=Reflect.ownKeys(b2)console.log(info2);//['name','age',Symbol(Wuhan)]如果Reflect.ownKeys()的参数不是对象,会报错Reflect.apply(func,thisArg,args)用于执行绑定此对象后的给定函数。如果想给行数绑定一个this对象,可以使用apply方法,但是持股函数定义了自己的apply方法,所以只能写成Function.prototype.apply.call(fn,obj,args)方法嵌套,而Reflect可以简化。letarr=[1,2,3,4,5,6,7]//旧方法leta=Math.min.apply(Math,arr)leta2=Math.max.apply(Math,arr)leta3=Object.prototype.toString.call(a)console.log(a);//1控制台日志(a2);//7控制台日志(a3);//[objectNumber]//新的写法leta4=Reflect.apply(Math.min,Math,arr)leta5=Reflect.apply(Math.max,Math,arr)leta6=Reflect.apply(Object.prototype.toString,a4,[])console.log(a4);//1控制台日志(a5);//7控制台日志(a6);//[objectNumber]apply方法:Function.apply(obj,args)方法可以接收两个参数范围。事实上,Reflect上的一些静态函数对应于ES2015之前Object上可用的方法,尽管有些方法在行为上看起来相似,但它们之间往往存在一些细微的差别。Reflect对象共有13个静态方法。下表详细说明了对象API和反射API上可用方法之间的差异。请注意,如果API中不存在某个方法,则会将其标记为N/A。ObjectReflectdefineProperty()Object.defineProperty()方法返回传递给函数的对象。如果未在对象上成功定义属性,则返回TypeError。如果在对象上定义了属性,则Reflect.defineProperty()返回true,否则返回false。defineProperties()Object.defineProperties()返回传递给函数的对象。如果未在对象上成功定义属性,则返回TypeError。N/Aset()N/A如果在对象上成功设置了属性,则Reflect.set()返回true,否则返回false。如果目标不是Object,则抛出TypeErrorget()N/AReflect.get()返回属性的值。如果目标不是Object,则抛出TypeError。deleteProperty()N/A如果属性从对象中删除,Reflect.deleteProperty()返回true,否则返回false。如果传入的对象参数上存在Object.getOwnPropertyDescriptor(),则getOwnPropertyDescriptor()返回给定属性的属性描述符,如果不存在,则返回未定义。Reflect.getOwnPropertyDescriptor()如果对象上存在给定属性,则返回给定属性的属性描述符。如果不存在则返回undefined,如果作为第一个参数符号传入的不是对象(原始值),则返回TypeError。如果传入的对象没有拥有属性描述符,则返回一个空对象。N/AgetPrototypeOf()Object.getPrototypeOf()返回给定对象的原型。如果没有继承的原型,则返回null。为ES5中的非对象引发TypeError,但在ES2015中强制为非对象。Reflect.getPrototypeOf()返回给定对象的原型。如果没有继承的原型,则返回null并为非对象抛出TypeError。setPrototypeOf()如果对象的原型设置成功,Object.setPrototypeOf()返回对象本身。如果原型集不是Object或null,或者被修改的对象的原型不可扩展,则抛出TypeError。如果在对象上成功设置了原型,则Reflect.setPrototypeOf()返回true,否则返回false(包括原型不可扩展的情况)。如果传入的目标不是Object,或者设置的原型不是Object或null,则抛出TypeError。isExtensible()如果对象是可扩展的,则Object.isExtensible()返回true,否则返回false。在ES5中,如果第一个参数不是对象(原始值)则抛出TypeError。在ES2015中,它将被强制转换为不可扩展的普通对象并返回false。如果对象是可扩展的,则Reflect.isExtensible()返回true,否则返回false。如果第一个参数不是对象(原始值),则抛出TypeError。preventExtensions()Object.preventExtensions()返回一个不可扩展的对象。如果参数不是对象(是原始值),则在ES5中抛出TypeError。在ES2015中,参数被视为不可扩展的普通对象,并返回对象本身。如果对象变得不可扩展,Reflect.preventExtensions()返回true,否则返回false。如果参数不是对象(是原始值),则抛出TypeError。keys()Object.keys()返回一个字符串数组,这些字符串映射到目标对象自己的(可枚举的)属性键。如果目标不是对象,则在ES5中抛出TypeError,但在ES2015N/AownKeys()N/AReflect.ownKeys()中将非对象目标强制转换为对象,返回映射到目标对象本身属性键的属性名称数组。如果目标不是Object,则抛出TypeError。上表数据对比源链接:比较Reflect和Object方法案例源码:https://gitee.com/wang_fan_w/es6-science-institute如果您觉得本文对您有帮助,请点亮star