Reflect使用的一些总结

Reflect 的定义

Reflect 是一个内置的对象,它提供拦截 JavaScript 操作的方法。这些方法与 proxy handler 的方法相同。Reflect 不是一个函数对象,因此它是不可构造的。Reflect 的所有属性和方法都是静态的。

静态方法

  • Reflect.apply(target, thisArgument, argumentsList)
    对一个函数进行调用操作,同时可以传入一个数组作为调用参数。和 Function.prototype.apply() 功能类似。

  • Reflect.construct(target, argumentsList[, newTarget])
    对构造函数进行 new操作,相当于执行 new target(…args)

  • Reflect.defineProperty(target, propertyKey, attributes)
    和Object.defineProperty() 类似。如果设置成功就会返回 true

  • Reflect.deleteProperty(target, propertyKey)
    作为函数的delete操作符,相当于执行delete target[name]

  • Reflect.get(target, propertyKey[, receiver])
    获取对象身上某个属性的值,类似于target[name]

  • Reflect.getOwnPropertyDescriptor(target, propertyKey)
    类似于Object.getOwnPropertyDescriptor()。如果对象中存在该属性,则返回对应的属性描述符,否则返回undefined。

  • Reflect.getPrototypeOf(target)
    类似于 Object.getPrototypeOf()。

  • Reflect.has(target, propertyKey)
    判断一个对象是否存在某个属性,和 in 运算符 的功能完全相同。

  • Reflect.isExtensible(target)
    类似于 Object.isExtensible().

  • Reflect.ownKeys(target)
    返回一个包含所有自身属性(不包含继承属性)的数组。(类似于 Object.keys(),但不会受enumerable 影响).

  • Reflect.preventExtensions(target)
    类似于Object.preventExtensions()。返回一个Boolean。

  • Reflect.set(target, propertyKey, value[, receiver])
    将值分配给属性的函数。返回一个Boolean,如果更新成功,则返回true。

  • Reflect.setPrototypeOf(target, prototype)
    设置对象原型的函数。返回一个Boolean,如果更新成功,则返回 true。

我们发现这13个静态方法,与proxy代理的handler中13个方法的方法名是完全一致的,其实这些方法就是proxy代理的那些方法内部的默认实现,你可能觉得这句话不是很好理解,我们这里来用代码说明一下。

let obj = {name: 'mike'};
let proxy = new Proxy(obj, {});
proxy.name // 'mike'

上面的代码中,我们并没有配置handler中的get方法,可是proxy.name却可以正常获取name的属性值,现在我们怀疑在没有配置相关handler处理方法的情况下,会有一个默认的处理方法

下面我们再改造一下上面代码,添加一个get处理方法

let obj = {name: 'mike'};
let proxy = new Proxy(obj, {
    get(target, key){
        console.log('proxy get');
    }
});
proxy.name 
// 'proxy get'

我们发现,如果我们配置一个get的处理方法,但是我们并没有添加相应的返回语句的话,这里的proxy.name当然会拿不到值

那么结合Reflect我们来试试吧

let obj = {name: 'mike'};
let proxy = new Proxy(obj, {
    get(target, key){
        console.log('proxy get');
        return Reflect.get(target, key);
    }
});
proxy.name
//proxy get
//'mike'

这下我们确定了,Reflect的静态方法就是Proxy处理对象那些方法内部的默认实现.

而且这种写法非常简洁漂亮,毕竟在ES5就有减少魔法、让代码更加纯粹的理念.

这种理念很大程度上是受到函数式编程的影响,ES6进一步贯彻了这种理念,它认为,对属性内存的控制、原型链的修改、函数的调用等等,这些都属于底层实现,属于一种魔法,因此,需要将它们提取出来,形成一个正常的API,并高度聚合到某个对象中,于是,就造就了Reflect对象

因此,你可以看到Reflect对象中有很多的API都可以使用过去的某种语法或其他API实现。

所以,我们可以使用Reflect的静态方法来代替对象的操作方式,我们看看下面

let obj = {name: 'mike'};
  • 获取对象上的属性值
Reflect.get(obj, 'name'); //'mike'
  • 给属性添加属性
Reflect.set(obj, 'age', 18); // true
obj // {name: 'mike', age: 18}
  • 判断对象是否有某个属性
Reflect.has(obj, 'name') // true
  • 删除对象的属性
Reflect.deleteProperty(obj, 'name') // true
obj //{age: 18}

通过定义属性的方式给对象添加属性

Reflect.defineProperty(obj, 'sex', {value: 'man'}); // true
obj // {age: 18, sex: 'man'}
  • 获取对象上的所有key(用Reflect的ownKeys获取不会受enumerable 影响)
Reflect.defineProperty(obj, 'sex', {value: 'man'}); // true
obj // {age: 18, sex: 'man'}
Reflect.ownKeys(obj) // ['age', 'sex']
Object.keys(obj) //['age']
for(let key in obj) {console.log(key)}
//age

举例就先到这里,不常用的这里不做赘述了,有需要的小伙伴可以自行体验哈~

所以,Reflect在配合proxy一起使用时,我们在自定义的get、set这样的处理方法中,更为标准的做法是,先去实现自己所需要的监视逻辑,最后再去返回通过Reflect中对应的方法的一个调用结果。

完结!

  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值