JS反射机制及Reflect详解
⼀、什么是反射机制
反射机制是在编译阶段不知道是哪个类被加载,⽽是在运⾏的时候才加载、执⾏。
也就是说,反射机制指的是程序在运⾏时能够获取⾃⾝的信息。
js中的apply就是反射机制。
⼆、Reflect
1、Reflect定义
Reflect是⼀个内建的对象,⽤来提供⽅法去拦截JavaScript的操作。
Reflect不是⼀个函数对象,所以它是不可构造的,也就是说它不是⼀个构造器,不能通过new操作符去新建或
者将其作为⼀个函数去调⽤Reflect对象。
Reflect的所有属性和⽅法都是静态的。
Reflect内部封装了⼀系列对对象的底层操作
Reflect成员⽅法就是Proxy处理对象的默认实现
constproxy=newProxy(obj,{
get(target,property){
//如果没有定义get⽅法,那么默认返回的就是Reflect的get⽅法
(target,property)
}
})
2、ReflectAPI汇总
Reflect提供了⼀套⽤于操作对象的API,我们之前操作对象可以⽤Object上⾯的⼀些⽅法,也可以⽤in、delete
这种操作符,使⽤Reflect就统⼀了操作⽅式
handler⽅法默认调⽤功能
()获取对象⾝上某个属性的值
()在对象上设置属性
()判断⼀个对象是否存在某个属性
Property()删除对象上的属性
totypeOf()获取指定对象原型的函数
totypeOf()设置或改变对象原型的函数
nsible()判断⼀个对象是否可扩展(即是否能够添加新的属性)
tExtensions()阻⽌新属性添加到对象
PropertyDescriptor()获取给定属性的属性描述符
Property()定义或修改⼀个对象的属性
s()返回由⽬标对象⾃⾝的属性键组成的数组
()
对⼀个函数进⾏调⽤操作,同时可以传⼊⼀个数组作为调⽤
参数
uct()对构造函数进⾏new操作,实现创建类的实例
.tExtensions()阻⽌新属性添加到对象
3、.apply()
(target,thisArgument,argumentsList)
target:⽬标函数(必选)
thisArgument:target函数调⽤时绑定的this对象(可选)
argumentsList:target函数调⽤时传⼊的实参列表,该参数应该是⼀个类数组的对象(可选)
①ES5⽤法
先指定⽅法,再去调⽤apply
(null,[1.72])//1
②ES6⽤法
先传递apply,再指定是哪个⽅法
(,null,[1.72])//1
静态扫描时是没有被执⾏,等到运⾏时再动态的将作为参数传进来的
③实际应⽤
//ES5⽤法
letprice=101.5
if(price>100){
price=(null,[price])
}el{
price=(null,[price])
}
price//101
//ES6⽤法
letprice=101.5
(price>100?:,null,[price])//101
4、.construct()
使⽤反射的⽅式去实现创建类的实例,类似于newtarget(…args)
uct(target,argumentsList[,newTarget])
target:被运⾏的⽬标函数(必选)
argumentsList:调⽤构造函数的数组或者伪数组(可选)
newTarget:该参数为构造函数,参考操作符,如果没有newTarget参数,默认和target⼀
样(可选)
①ES5⽤法
leta=newDate()
e()//83
②ES6⽤法
letb=uct(Date,[])
e()//84
5、.defineProperty()
静态⽅法Property()基本等同于Property()⽅法
Property(target,propertyKey,attributes)
target:⽬标对象(必选)
propertyKey:要定义或修改的属性的名称(可选)
attributes:要定义或修改的属性的描述(可选)
①ES5⽤法
conststudent={}
constr=Property(student,'name',{value:'Mike'})
student//{name:"Mike"}
r//{name:"Mike"}
②ES6⽤法
conststudent={}
constr=Property(student,'name',{value:'Mike'})
student//{name:"Mike"}
r//true
这两个⽅法效果上来看是⼀摸⼀样的,都可以改变⼀个对象的值
区别在于返回值不同:Object是返回这个值,Reflect是返回true
PS:在W3C中,以后所有的Object上⾯的⽅法,都会慢慢迁移到Reflect对象,可能以后会在Object
上⾯移除这些⽅法
6、.deleteProperty()
Property允许你删除⼀个对象上的属性,返回⼀个Boolean值表⽰该属性是否被成功删除,它⼏乎
与⾮严格的deleteoperator相同
Property(target,propertyKey)
target:删除属性的⽬标对象
propertyKey:将被删除的属性的名称
①ES5⽤法
constobj={x:1,y:2}
consta=deleteobj.x
obj//{y:2}
a//true
②ES6⽤法
constobj={x:1,y:2}
consta=Property(obj,'x')
obj//{y:2}
a//true
7、.get()
()⽅法的⼯作⽅式,就像从object(target[propertyKey])中获取属性,但它是作为⼀个函数执⾏的
(target,propertyKey[,receiver])
①ES5⽤法
constobj={x:1,y:2}
obj.x//1
obj['x']//1
②ES6⽤法
constobj={x:1,y:2}
(obj,'x')//1
(['a','b','c'],1)//b
8、.getOwnPropertyDescriptor()
静态⽅法PropertyDescriptor()与PropertyDescriptor()⽅法相似
如果在对象中存在,则返回给定的属性的属性描述符,否则返回undefined
PropertyDescriptor(target,propertyKey)
①ES5⽤法
constobj={x:1,y:2}
PropertyDescriptor(obj,'x')
//{value:1,writable:true,enumerable:true,configurable:true}
②ES6⽤法
constobj={x:1,y:2}
PropertyDescriptor(obj,'x')
//{value:1,writable:true,enumerable:true,configurable:true}
PropertyDescriptor({x:'hello'},'y')
//undefined
PropertyDescriptor([],'length')
//{value:0,writable:true,enumerable:fal,configurable:fal}
③对⽐
如果PropertyDescriptor的第⼀个参数不是⼀个对象(⼀个原始值),那么将造成TypeError错误
⽽对于PropertyDescriptor,⾮对象的第⼀个参数将被强制转换为⼀个对象处理
PropertyDescriptor("foo",0);
//TypeError:"foo"isnotnon-nullobject
PropertyDescriptor("foo",0);
//{value:"f",writable:fal,enumerable:true,configurable:fal}
9、.getPrototypeOf()
静态⽅法totypeOf()与totypeOf()⽅法是⼀样的,都是返回指定对象的原型(即,内部
的[[Prototype]]属性的值)
totypeOf(target)
①ES5⽤法
constd=NewDate()
totypeOf(d)
//{constructor:ƒ,toString:ƒ,toDateString:ƒ,toTimeString:ƒ,toISOString:ƒ,…}
②ES6⽤法
constd=NewDate()
totypeOf(d)
//{constructor:ƒ,toString:ƒ,toDateString:ƒ,toTimeString:ƒ,toISOString:ƒ,…}
10、.has()
判断⼀个对象是否存在某个属性,和in运算符的功能完全相同
(target,propertyKey)
constobj={x:1,y:2}
(obj,'x')//true
(obj,'z')//fal
11、.isExtensible()
判断⼀个对象是否可扩展
nsible与nsible⽅法⼀样,都是判断⼀个对象是否可扩展(即是否能够添加新的属性)
nsible(target)
constobj={x:1,y:2}
nsible(obj)//true
(obj)//阻⽌新属性添加到对象
obj.z=3
nsible(obj)//fal
obj//{x:1,y:2}
12、.ownKeys()
判断对象⾃⾝属性
s⽅法返回⼀个由⽬标对象⾃⾝的属性键组成的数组,它的返回值等同于
`PropertyNames(target).concat(PropertySymbols(target))
s(target)
constobj={x:1,y:2}
s(obj)//["x","y"]
s([])//["length"]
s([1,2])//["0","1","length"]
13、.preventExtensions()
阻⽌新属性添加到对象,等同于()
tExtensions⽅法阻⽌新属性添加到对象,例如:防⽌将来对对象的扩展被添加到对象中,与
tExtensions()⽅法⼀致
tExtensions(target)
constobj={x:1,y:2}
nsible(obj)//true
tExtensions(obj)//阻⽌新属性添加到对象
obj.z=3
nsible(obj)//fal
obj//{x:1,y:2}
14、.t()
写数据
⽅法允许你在对象上设置属性,⽤来给属性赋值,类似propertyaccessor的语法,但它是以函数的⽅
式
(target,propertyKey,value[,receiver])
constobj={x:1,y:2}
(obj,'z',4)
obj//{x:1,y:2,z:4}
constarr=['apple','pear']
(arr,1,'banana')
arr//["apple","banana"]
15、.tPrototypeOf()
totypeOf⽅法改变指定对象的原型(即内部的[[Prototype]]属性值)
totypeOf(target,prototype)
constarr=['apple','pear']
totypeOf(arr)
//[constructor:ƒ,concat:ƒ,copyWithin:ƒ,fill:ƒ,find:ƒ,…]
totypeOf(arr,ype)
totypeOf(arr)
//String{"",constructor:ƒ,anchor:ƒ,big:ƒ,blink:ƒ,…}
本文发布于:2022-12-26 17:36:19,感谢您对本站的认可!
本文链接:http://www.wtabcd.cn/fanwen/fan/90/35065.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |