一、什么是反射机制
反射机制是在编译阶段不知道是哪个类被加载,而是在运行的时候才加载、执行。
也就是说,反射机制指的是程序在运行时能够获取自身的信息。
js 中的 apply 就是反射机制。
Reflect 是一个内建的对象,用来提供方法去拦截 JavaScript 的操作。
Reflect 不是一个函数对象,所以它是不可构造的,也就是说它不是一个构造器,不能通过 new 操作符去新建或者将其作为一个函数去调用 Reflect 对象。
Reflect 的所有属性和方法都是静态的。
Reflect 内部封装了一系列对对象的底层操作
Reflect 成员方法就是 Proxy 处理对象的默认实现
Reflect 提供了一套用于操作对象的 API,我们之前操作对象可以用 Object 上面的一些方法,也可以用 in、delete 这种操作符,使用 Reflect 就统一了操作方式
handler ⽅法 默认调⽤ 功能get Reflect.get() 获取对象身上某个属性的值
set Reflect.set() 在对象上设置属性
has Reflect.has() 判断一个对象是否存在某个属性
deleteProperty Reflect.deleteProperty() 删除对象上的属性
getProperty Reflect.getPrototypeOf() 获取指定对象原型的函数
setProperty Reflect.setPrototypeOf() 设置或改变对象原型的函数
isExtensible Reflect.isExtensible() 判断一个对象是否可扩展 (即是否能够添加新的属性)
preventExtensions Reflect.preventExtensions() 阻止新属性添加到对象
getOwnPropertyDescriptor Reflect.getOwnPropertyDescriptor() 获取给定属性的属性描述符
defineProperty Reflect.defineProperty() 定义或修改一个对象的属性
ownKeys Reflect.ownKeys() 返回由目标对象自身的属性键组成的数组
apply Reflect.apply() 对一个函数进行调用操作,同时可以传入一个数组作为调用参数
construct Reflect.construct() 对构造函数进行 new 操作,实现创建类的实例
.preventExtensions Reflect.preventExtensions() 阻止新属性添加到对象
3、.apply()
Reflect.apply(target, thisArgument, argumentsList)
target:目标函数(必选)
thisArgument:target 函数调用时绑定的 this 对象(可选)
argumentsList:target 函数调用时传入的实参列表,该参数应该是一个类数组的对象(可选)
① ES5 用法先指定方法,再去调用 apply
Math.floor.apply(null, [1.72]) // 1 ② ES6 用法先传递 apply,再指定是哪个方法
Reflect.apply(Math.floor, null, [1.72]) // 1静态扫描时 Math.floor 是没有被执行,等到运行时再动态的将 Math.floor 作为参数传进来的
③ 实际应用 // ES5 用法 let price = 101.5 if (price > 100) { price = Math.floor.apply(null, [price]) } else { price = Math.ceil.apply(null, [price]) } price // 101 // ES6 用法 let price = 101.5 Reflect.apply(price > 100 ? Math.floor : Math.ceil, null, [price]) // 101 4、.construct()使用反射的方式去实现创建类的实例,类似于 new target(…args)
Reflect.construct(target, argumentsList[, newTarget])
target:被运行的目标函数(必选)
argumentsList:调用构造函数的数组或者伪数组(可选)
newTarget:该参数为构造函数, 参考 new.target 操作符,如果没有 newTarget 参数, 默认和 target 一样(可选)
① ES5 用法 let a = new Date() a.getTime() // 1632632744483 ② ES6 用法 let b = Reflect.construct(Date, []) b.getTime() // 1632632744484 5、.defineProperty()静态方法 Reflect.defineProperty() 基本等同于 Object.defineProperty() 方法
Reflect.defineProperty(target, propertyKey, attributes)
target:目标对象(必选)
propertyKey:要定义或修改的属性的名称(可选)
attributes:要定义或修改的属性的描述(可选)
① ES5 用法 const student = {} const r = Object.defineProperty(student, 'name', { value: 'Mike' }) student // {name: "Mike"} r // {name: "Mike"} ② ES6 用法 const student = {} const r = Reflect.defineProperty(student, 'name', { value: 'Mike' }) student // {name: "Mike"} r // true这两个方法效果上来看是一摸一样的,都可以改变一个对象的值
区别在于返回值不同:Object是返回这个值,Reflect是返回true
PS: 在 W3C 中,以后所有的 Object 上面的方法,都会慢慢迁移到 Reflect 对象,可能以后会在 Object 上面移除这些方法
6、.deleteProperty()