js 对象反射 Reflect
Reflect 是 es6 内置的对象,它用于对象的反射,比 eval 动态执行要方便得多。
动态执行
Reflect.apply(target, thisArgument, argumentsList)
第一个是函数名称,或者对象.方法,或者对象[方法],
第二个是要绑定的this,写null,那么在反射时它再使用this就是null了,所以对象的话,要传入实例本身
第三个是一个数组,比如2个参数,那么[参数1,参数2]
动态创建对象
Reflect.construct(target, argumentsList[, newTarget])
相当于运行 new target(...args).
第三个参数,作为新创建对象的原型对象的 constructor 属性,参考 new.target 操作符,默认值为 target 本身。
增加修改属性
Reflect.defineProperty(target, propertyKey, attributes)
第一个是对象
第二个是属性名
第三个是定义、或者修改的属性值,格式是 {value : 设置的值}
删除属性
Reflect.deleteProperty(target, propertyKey)
target
删除属性的目标对象。
propertyKey
需要删除的属性的名称。
获取属性值
Reflect.get(target, propertyKey[, receiver])
target
需要取值的目标对象
propertyKey
需要获取的值的键值
receiver
如果target对象中指定了getter,receiver则为getter调用时的this值。
获取属性描述
Reflect.getOwnPropertyDescriptor(target, propertyKey)
target
需要寻找属性的目标对象。
propertyKey
获取自己的属性描述符的属性的名称。
Reflect.getOwnPropertyDescriptor({ x: "hello" }, "x");
// {value: "hello", writable: true, enumerable: true, configurable: true}
Reflect.getOwnPropertyDescriptor({ x: "hello" }, "y");
// undefined
Reflect.getOwnPropertyDescriptor([], "length");
// {value: 0, writable: true, enumerable: false, configurable: false}
获取对象原型
Reflect.getPrototypeOf(target)
参数
target
获取原型的目标对象。
返回值
给定对象的原型。如果给定对象没有继承的属性,则返回 null。
是否存在属性
Reflect.has(target, propertyKey)
参数
target
目标对象。
propertyKey
属性名,需要检查目标对象是否存在此属性。
返回值
一个 Boolean 类型的对象指示是否存在此属性。
对象能否扩展
Reflect.isExtensible(target)
默认情况下,对象是可扩展的:可以向它们添加新属性,并且它们的 [[Prototype]] 可以被重新赋值。可以使用 Object.preventExtensions()、Object.seal()、Object.freeze() 或 Reflect.preventExtensions() 中的任一方法将对象标记为不可扩展。
获取自身的键
Reflect.ownKeys(target)
target
获取自身属性键的目标对象。
返回值
由目标对象的自身属性键组成的 Array。
禁止扩展对象
Reflect.preventExtensions(target)
参数
target
阻止扩展的目标对象。
返回值
返回一个 Boolean 值表明目标对象是否成功被设置为不可扩展。
可以通过 isExtensible 查看是否可以扩展
动态设置属性
Reflect.set(target, propertyKey, value)
Reflect.set(target, propertyKey, value, receiver)
target
设置属性的目标对象。
propertyKey
设置的属性的名称。
value
设置的值。
receiver
如果遇到 setter,receiver则为setter调用时的this值。
返回值
返回一个 Boolean 值表明是否成功设置属性。
这里和 propertity 方法对比的话,常用的应该是 set ,因为 definePropertify 的参数是一个对象,这里只是一个值
动态设置原型对象
Reflect.setPrototypeOf(target, prototype)
target
设置原型的目标对象。
prototype
对象的新原型(一个对象或 null)。
返回值
返回一个 Boolean 值表明是否原型已经成功设置。
关于Object
js里的object是继承于Function,所以一个 class 使用 typeof ,它会是 function
比如
class A {
b=null;
c(){
}
static d(){
}
}
此时,有一个 class 为 a,当你使用 typeof A,它就是 function,然后你想判断是否有静态方法,应该用 typeof A["d"] === "function",判断是否有实例方法c,那么应该 typeof new A()["c"] === "function",如果使用 Reflect 可能无法达到需求,因为 is 仅仅判断实例是否有属性/方法,静态都无法判断了,getOwnPropertyDescriptor 它只能判断属性无法判断方法。
还有一种字符串的方法调用,假设字符串 method = "abc";
动态执行对象的静态方法,类[method](),动态执行实例方法 new 类()[method](),它可以很方便的反射类/实例上的方法。
所以 Reflect 并不是万能的,首先要了解 Object 对象,我们使用 Reflect 一般是 apply 比较多,对象的get、set 一般是可以直接操作的,可能用不到 Reflect。
文章作者: 朱丰华
文章链接: https://smart.52dixiaowo.com/blog/post-519.html
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。