当前位置: 首页 > Web前端 > HTML5

ES6(十二)——Reflect

时间:2023-04-05 17:02:25 HTML5

Reflect反射,什么是反射机制?Reflect简介为什么要使用Reflect?体现API.apply().construct().defineProperty().deleteProperty().get().getOwnPropertyDescriptor().getPrototypeOf().has().isExtensible()——是否可扩展。ownKeys()——判断对象本身的属性。preventExtensions()—是否可以扩展。set()——写入数据。setPrototypeOf()ES6-ES10学习布局反射,什么是反射机制?【Java的反射机制】在编译阶段不知道加载了哪个类,而是在运行时加载并执行。js中的apply就是反射机制。Reflect简介Reflect是一个内置对象,它提供了拦截JavaScript操作的方法,与处理器对象的方法相同。Reflect不是一个函数对象,所以它是不可构造的。与大多数全局对象不同,Reflect没有构造函数。您不能将它与new运算符一起使用,也不能将Reflect对象作为函数调用。Reflect的所有属性和方法都是静态的(就像Math对象一样)。为什么要使用反射?Reflect内部封装了一系列对对象的底层操作。Reflect成员方法是Proxy处理对象的默认实现。constproxy=newProxy(obj,{get(target,property){//如果没有定义get方法,默认返回是Reflect的get方法returnReflect.get(target,property)}})为什么使用反映?
由于Reflect提供了一套操作对象的API,我们可以在操作对象之前先在Object上使用一些方法,或者使用in、delete等操作符。使用Reflect统一了操作模式。ReflectAPIhandler方法默认调用函数getReflect.get()获取对象的某个属性的值setReflect.set()设置对象的属性hasReflect.has()判断对象是否具有某个属性deletePropertyReflect.deleteProperty()删除对象上的属性getPropertyReflect.getPrototypeOf()获取指定对象原型的函数setPropertyReflect.setPrototypeOf()设置或改变对象原型的函数isExtensibleReflect.isExtensible()判断一个对象是否可扩展(即是否可以添加新属性)preventExtensionsReflect.preventExtensions()防止向对象添加新属性getOwnPropertyDescriptorReflect.getOwnPropertyDescriptor()获取给定属性的属性描述符definePropertyReflect.defineProperty()定义或修改对象的属性ownKeysReflect.ownKeys()返回目标对象自身属性键的数组applyReflect.apply()调用一个函数,可以传入一个数组作为调用参数。constructReflect.construct()对构造函数执行新操作以创建类的实例。preventExtensionsReflect.preventExtensions()防止将新属性添加到对象。apply()Reflect.apply(target,thisArgument,argumentsList)target:目标函数,必须传入
thisArgument:调用目标函数时绑定的this对象,不需要
argumentsList:传入时传入targetfunctioniscalled实参列表,参数应该是类数组对象,不一定//ES5console.log(Math.floor.apply(null,[1.72]))//1//必须指定方法在调用apply之前。//reflect是一个对象,但是不能用new//先通过apply,然后指定是哪个方法//静态扫描的时候,Math.floor是不执行的。运行时,动态使用Math.floor作为传入的参数。Reflect.apply(Math.floor,null,[4.72])//4实际应用//ES5letprice=101.5if(price>100){price=Math.floor.apply(null,[price])}else{price=Math.ceil.apply(null,[price])}console.log(price)//101//ES6letprice=101.5console.log(Reflect.apply(price>100?Math.floor:Math.ceil,null,[price]))//101.construct()使用反射创建类的实例,类似于newtarget(...args).Reflect.construct(target,argumentsList[,newTarget])target:tobe执行的Target函数,需要
argumentsList调用构造函数的数组或伪数组,不需要
newTarget这个参数是一个构造函数,参考new.target操作符,如果没有newTarget参数,则默认和target一样,不需要Selectletd=newDate()console.log(d.getTime())letd1=Reflect.construct(Date,[])console.log(d1.getTime())。defineProperty()静态方法Reflect.defineProperty()基本等同于Object.defineProperty()方法Reflect.defineProperty(target,propertyKey,attributes)target:目标对象,required
propertyKey:要定义的属性名称ormodified,notrequired
attributes:定义或修改的属性的描述不必填写conststudent={}constr=Object.defineProperty(student,'name',{value:'Mike'})console.log(student,r)//{name:"Mike"}{name:"Mike"}conststudent={}constr=Reflect.defineProperty(student,'name',{value:'Mike'})console.log(student,r)//{name:"Mike"}true这两个方法在效果上是完全一样的,都可以改变一个对象的值,它们的区别在于返回值不同。Object返回这个值,Reflect返回truePS:在W3C中,Object上的所有方法以后都会逐渐迁移到Reflect对象上,将来可能会将这些方法从Object中去掉。.deleteProperty()Reflect.deleteProperty允许您删除对象的属性。返回一个布尔值,指示属性是否已成功删除。它与非严格删除运算符几乎相同。Reflect.deleteProperty(target,propertyKey)target:要删除属性的目标对象
propertyKey:要删除的属性名constobj={x:1,y:2}deleteobj.xconsole.log(obj)//{y:2}constobj={x:1,y:2}constd=Reflect.deleteProperty(obj,'x')console.log(obj,d)//{y:2}true.get()Reflect.get()方法的工作方式类似于从对象(target[propertyKey])获取属性,但它作为函数执行。Reflect.get(target,propertyKey[,receiver])constobj={x:1,y:2}console.log(obj.x)//1console.log(obj['x'])//1constobj={x:1,y:2}console.log(Reflect.get(obj,'x'))//1console.log(Reflect.get([3,4],1))//4.getOwnPropertyDescriptor()静态方法Reflect.getOwnPropertyDescriptor()类似于Object.getOwnPropertyDescriptor()方法。如果对象中存在给定属性,则返回给定属性的属性描述符,否则返回未定义。Reflect.getOwnPropertyDescriptor(target,propertyKey)constobj={x:1,y:2}console.log(Object.getOwnPropertyDescriptor(obj,'x'))//{value:1,writable:true,enumerable:true,configurable:true}console.log(Reflect.getOwnPropertyDescriptor(obj,'x'))//{value:1,writable:true,enumerable:true,configurable:true}console.log(Reflect.getOwnPropertyDescriptor({x:'hello'},'y'))//undefinedconsole.log(Reflect.getOwnPropertyDescriptor([],'length'))//{value:0,writable:true,enumerable:false,configurable:false}比较这个方法如果第一个参数不是对象(原始值),则会引发TypeError。而对于Object.getOwnPropertyDescriptor,非对象的第一个参数会被强制转换成对象处理。Reflect.getOwnPropertyDescriptor("foo",0);//TypeError:"foo"不是非空objectObject.getOwnPropertyDescriptor("foo",0);//{value:"f",writable:false,enumerable:true,configurable:false}.getPrototypeOf()静态方法Reflect.getPrototypeOf()与Object.getPrototypeOf()方法相同。两者都返回指定对象的原型(即内部[[Prototype]]属性的值)。Reflect.getPrototypeOf(target)constd=NewDate()console.log(Reflect.getPrototypeOf(d))//{constructor:?,toString:?,toDateString:?,toTimeString:?,toISOString:?,…}控制台.log(Object.getPrototypeOf(d))//{constructor:?,toString:?,toDateString:?,toTimeString:?,toISOString:?,...}.has()判断一个对象是否具有某个属性,和in运算符的功能完全一样。Reflect.has(target,propertyKey)constobj={x:1,y:2}console.log(Reflect.has(obj,'x'))//trueconsole.log(Reflect.has(obj,'z'))//false.isExtensible()——是否可扩展Reflect.isExtensible判断一个对象是否可扩展(即是否可以添加新的属性),与Object.isExtensible()方法相同。Reflect.isExtensible(target)constobj={x:1,y:2}console.log(Reflect.isExtensible(obj))//trueObject.freeze(obj)obj.z=3console.log(Reflect.isExtensible(obj)))//falseconsole.log(obj)//{x:1,y:2}.ownKeys()——判断对象自身属性。Reflect.ownKeys方法返回一个由目标对象自身的属性键组成的数组。它的返回值相当于Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target))Reflect.ownKeys(target)constobj={x:1,y:2}console.log(Reflect.ownKeys(obj))//["x","y"]console.log(Reflect.ownKeys([]))//["length"]console.log(Reflect.ownKeys([1,2]))//["0","1","length"].preventExtensions()–是否可扩展或等效于Object.freeze()Reflect.preventExtensions方法防止新属性被添加到对象例如:防止将来扩展到对象从被添加到对象)。这个方法和Object.preventExtensions()方法是一致的.z=3console.log(Reflect.isExtensible(obj))//falseconsole.log(obj)//{x:1,y:2}.set()-写入数据Reflect.set方法允许你设置属性在物体上。它的作用是为属性赋值,类似于属性访问器语法,但是以函数式的方式。Reflect.set(target,propertyKey,value[,receiver])constobj={x:1,y:2}Reflect.set(obj,'z',4)console.log(obj)//{x:1,y:2,z:4}constarr=['apple','pear']Reflect.set(arr,1,'banana')console.log(arr)//["apple","banana"].setPrototypeOf()Reflect.setPrototypeOf方法改变指定对象的原型(即内部的[[Prototype]]属性值)Reflect.setPrototypeOf(target,prototype)constarr=['apple','pear']console.log(Reflect.getPrototypeOf(arr))//[构造函数:?,concat:?,copyWithin:?,填充:?,查找:?,…]Reflect.setPrototypeOf(arr,String.prototype)console.log(Reflect.getPrototypeOf(arr))//String{"",constructor:?,anchor:?,big:?,blink:?,…}ES6-ES10学习布局