ES6 Reflect使用笔记
reflect
reflect 对象和proxy对象一样, 为操作对象提供了新的api。
为什么使用 reflect的方式来操作对象?
将 object 对象上一些明显属于内部的方法放到 reflect对象上。比如
object.defindproperty
也可以使用reflect.defindproperty
修改某些 object 方法的返回结果
让 object 操作都变成函数行为。
reflect 对象的操作方法和 proxy的方法一一对应, 很方便 proxy对象来调用 reflect 方法
例子:
const sum = function (num1, num2) { return num1 + num2 } const proxy = new proxy(sum, { apply(target, context, args) { return reflect.apply(...arguments) * 2 } }) proxy(1,2) // 6
以上代码 proxy 的配置方法 apply和 reflect的apply方法是对应关系,直接通过 reflect.apply
来调用拦截函数 sum
。并将函数执行后的结果 * 2。最终的结果是 6。
#### reflect 对象和 proxy的静态方法一样,同样是13个。
- reflect.apply(target, context, args)
- reflect.get(target, key, context)
- reflect.set(target, key, value, context)
- reflect.construct(target, args)
- reflect.defindproperty(target, key, desc)
- reflect.has(target, key)
- reflect.deleteproperty(target, key)
- reflect.setproperty(target, proto)
- reflect.getproperty(target)
- reflect.ownkeys(target)
- reflect.isextensible(target)
- reflect.preventextensions(target)
- reflect.getownpropertydescriptor(target, key)
reflect.get(target, key, context)
target
: 查找的对象key
: 查找的属性context
: 读取getter函数的上下文对象
const obj = { name: 'qiqingfu', get sayname() { console.log(this.name) } } const obj1 = { name: 'zhangfei' } reflect.get(obj, 'name') // qiqingfu reflect.get(obj, 'sayname', obj1) // zhangfei
如果第一个参数不是对象, reflect.get
方法会报错。
reflect.set(target, key, value, context)
target
: 要给哪个对象设置key
: 要设置的属性value
: 设置的值返回值
: boolean
const obj = { value: 1, set fn(newvalue) { return this.value = newvalue } } console.log(reflect.set(obj, 'name', 'qiqingfu')) // true console.log(reflect.set(obj, 'fn', 2)) console.log(obj)
以上代码,给obj对象设置了一个name
属性,其值为qiqingfu
, 并且设置fn
的时候被get
函数拦截到了。
reflect.has(target, key) 方法检测 target对象上有么有 key这个属性
返回值
: boolean
const obj = { name: 'qiqingfu', a: 2 } console.log(reflect.has(obj, 'name')) // true console.log(reflect.has(obj, 'a')) // true console.log(reflect.has(obj, 'b')) // false
其实 reflect.has
和 in
操作符类似。
reflect.construct(target, args) 方法用于类似于 new 操作符
target
: 目标函数args
: 实例化对象需要传递的参数 array返回值
: 实例对象
function prosen (name, age) { this.name = name; this.age = age } const prosen = reflect.construct(prosen, ['qiqingfu', 22]) // {name: 'qiqingfu', age: 22}
以上代码使用 reflect.construct
方法实例话一个对象,接受的参数为数组类型
reflect.defineproperty(target, key, decs) 和 object.defineproperty(target, key, decs) 一样
更推崇使用前者。
方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
const obj = { } reflect.defineproperty(obj, 'a', { value: 1, configurable: true, // 可配置 writable: true // 可写 }) // {a: 1}
以上代码给 obj 对象添加了一个 a属性, 其值为1并且是可配置和可修改的
reflect.deleteproperty(target, key) 方法删除 target对象的key属性
const obj = { a: 1 } reflect.defindproperty(obj, 'a') console.log(obj) // {}
reflect.getpropertyof(target) 方法获取一个对象的原型对象
function prosen() { } prosen.prototype.age = 21 const prosen = reflect.construct(prosen, []) // 获取原型对象的属性 const proto = reflect.getprototypeof(prosen) console.log(proto) // {age: 21, constructor: ƒ}
以上代码 给 prosen 构造函数的原型对象上添加了一个 age属性。并且通过 reflect.construct
方法实例化一个对象。那么就可以通过 reflect.getprototypeof
方法获取一个对象的原型对象。
reflect.setprototypeof(target, proto) 方法将 proto设置为 target对象的原型对象
function prosen() { } prosen.prototype.age = 21 const prosen = reflect.construct(prosen, []) // 设置prosen 的原型对象 reflect.setprototypeof(prosen, {b: 2})
此时, prosen的原型对象为 {b:2}, 而 construct
指针会被覆盖
reflect.ownkeys(target) 获取对象的key值,返回值为数组
和 object.ownkeys
相同。
const obj = { a: 1, [symbol('c')]: 3, } reflect.defineproperty(obj, 'b', { value: 2, configurable: true, enumerable: true }) console.log(reflect.ownkeys(obj)) // ["a", "b", symbol(c)]
返回值是一个数组, 存放着对象的 key值的集合。
reflect.getownpropertydescriptor(target, key) 方法获取一个对象key值的描述对象
返回值
: object
const obj = { a: 1, [symbol('c')]: 3, } reflect.defineproperty(obj, 'b', { value: 2, configurable: true, enumerable: true }) const decs = reflect.getownpropertydescriptor(obj, 'b') console.log(decs) /* {value: 2, writable: false, enumerable: true, configurable: true} */
以上代码通过 reflect.getownpropertydescriptor
方法获取一个对象属性的描述对象, 如果第一个参数不是对象会报错。而在 object.getownpropertydescriptor
不会报错,只不过返回 undefind
下一篇: 离婚了还能挽回吗?方法在这里