Reflect javascript

Reflect是ES6提供的新对象

将Object对象的一些明显属于语言内部的方法(比如Object.defineProperty,Proxy对象上所有新增函等),放到Reflect对象上。

让Object的操作都变成函数行为。某些Object操作是命令式,比如name in obj 和
delete obj[name], 而Reflect.has(obj, name) 和 Reflect.deleteProperty(obj, name) 让它们变成了函数行为。
如:

let obj = {
  name:'zhangsan'
}
obj.name = 'lisi';
console.log(obj)//{name:'lisi'}

这是一个普通的不能再普通的对象属性赋值操作,设置成功后obj对象的name属性值变为’lisi’。然而某些情况下操作失败时,要么是不友好的报错,要么用户并无感知,导致找不到bug出处。
如程序员甲给obj的name属性设置了不可写:

let obj = {
  name:'zhangsan'
}
Object.defineProperty(obj,'name',{
    writable:false
})
obj.name = 'lisi';
console.log(obj)//{name:'张三'}

程序员乙通过obj.name = 'lisi’设置了name属性的值,然而name属性的值未改变,莫名其妙。如果通过Reflect提供的api代替.操作符进行的属性访问和设置操作,就可明显感知操作的成败,然后再编写后续的逻辑。

let obj = {
  name:'zhangsan'
}
Object.defineProperty(obj,'name',{
    writable:false
})
obj.name = 'lisi';
var  result = Reflect.set(obj,'name','lisi');
if(result ){
  console.log(obj)//当属性可写的情况下成功更改属性的值
}else{
  console.log('name属性值修改失败,请检查是否设置了不可写,或其他原因')
}

根据以上理论,可将Proxy代理改写的更合理:

let objs = {
  name:'zhangsan',
  password:'123456'
}
Object.defineProperty(objs,'name',{
    writable:false
});
let proxy=new Proxy(objs,{
  set(target,key,value){
    let isSuccess=Reflect.set(target,key,value);
    if(!isSuccess){
      throw new Error('值设置失败');
    }
    return isSuccess
  }
})
proxy.name = 18;
console.log(objs);
//Uncaught Error: 值设置失败

Reflect 对象的方法与Proxy 对象的方法一一对应, 只要是Proxy 对象上的方法, 就能在Reflect 对象上找到对应的方法。这就使Proxy对象可以方便地调用对应Reflect的方法来完成默认行为,作为修改行为的基础。无论Proxy怎么修改默认行为,我们总可以在Reflect上获取默认行为

const des = {
    name: 'liu',
    age: 18
};
const newDes = new Proxy(des, {
    set: function (target, name, value, receiver) {
        let res = Reflect.set(target, name, value, receiver);
        // 额外行为
        if (res) {
            console.log(res)
            Reflect.set(target, 'age', 80, receiver);
        }
        return res
    }
});
console.log(newDes);
newDes.name = 'xxxx';
console.log(newDes);

我们对 对象des 的set 方法 做了一层拦截, 每当newDes 设置值的时候,我们先用

Reflect.set() 保证默认行为, 默认行为成功后 再执行我们的额外行为,也就是把age 变成80.

看下执行结果:

在这里插入图片描述

OK , 默认行为name设置成功, 额外行为age也设置成功,

我们还可以代理对象内部的其他方法:

const des = {
    name: 'liu',
    age: 18
};
const newDes = new Proxy(des, {
    set(target, name, value, receiver) {
        let res = Reflect.set(target, name, value, receiver);
        // 额外行为
        if (res) {
            console.log(res);
            Reflect.set(target, 'age', 80, receiver);
        }
        return res
    },
    deleteProperty(target, p) {
        console.log('delete ' + p);
        return Reflect.deleteProperty(target, p);
    },
    get(target, p, receiver) {
        console.log('get ' + p);
        return Reflect.get(target, p, receiver);
    }
});
const name = newDes.name;
delete newDes.age;

拦截对象的get方法 和 delete 指令
结果:
在这里插入图片描述
拦截成功。
转载文章:https://www.jianshu.com/p/2f597dae07b3
http://t.zoukankan.com/LHLVS-p-11023963.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值