ES6的Reflect对象

42 篇文章 0 订阅
10 篇文章 0 订阅

Reflect

Reflect对象的设计目的有这样几个
  1. 将Object对象的一些明显属于语言内部的方法(比如Object.defineProperty),放到Reflect对象上。现阶段,某些方法同时在Object和Reflect对象上部署,未来的新方法将只部署在Reflect对象上。
  2. 修改某些Object方法的返回结果,让其变得更合理。比如,Object.defineProperty(obj, name, desc)在无法定义属性时,会抛出一个错误,而Reflect.defineProperty(obj, name, desc)则会返回false
  3. 让Object操作都变成函数行为。某些Object操作是命令式,比如name in obj和delete obj[name],而Reflect.has(obj, name)和Reflect.deleteProperty(obj, name)让它们变成了函数行为。
  4. Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法。这就让Proxy对象可以方便地调用对应的Reflect方法,完成默认行为,作为修改行为的基础。也就是说,不管Proxy怎么修改默认行为,你总可以在Reflect上获取默认行为。
方法跟Proxy的方法一一对应
//Reflect.apply(target,thisArg,args)
// Reflect.construct(target, args)
// Reflect.get(target, name, receiver)
// Reflect.set(target, name, value, receiver)
// Reflect.defineProperty(target, name, desc)
// Reflect.deleteProperty(target, name)
// Reflect.has(target, name)
// Reflect.ownKeys(target)
// Reflect.isExtensible(target)
// Reflect.preventExtensions(target)
// Reflect.getOwnPropertyDescriptor(target, name)
// Reflect.getPrototypeOf(target)
// Reflect.setPrototypeOf(target, prototype)

console.log('assign' in Object);    //true
console.log(Reflect.has(Object, 'assign'))  //true
 var obj = {
    get foo() { console.log(this); return this.bar(); },
    bar: function () { console.log('bar') },
    construct: function(target, args) {
        console.log('construct')
        return { value: args[1] };
    }
};

//定义一个cc类
var cc = {
    foo() { console.log('cc.foo')},
    bar() { console.log('cc.bar') }
};
// (1)Reflect.get(target, name, receiver)
console.log(Reflect.get(obj, 'bar'))
// 下面语句会让 this.bar()
//         // 变成调用 cc.bar()

         Reflect.get(obj, "foo", cc); //传递cc进去,就会改变this为cc
         
//         查找并返回target对象的name属性,如果没有该属性,则返回undefined。
//         如果name属性部署了读取函数,则读取函数的this绑定receiver。
//         var obj = {
//             get foo() { return this.bar(); },
//             bar: function () { ... }
// };

(2)Reflect.set(target, name, value, receiver)
设置target对象的name属性等于value。如果name属性设置了赋值函数,则赋值函数的this绑定receiver。
如果target对象中指定了getter,receiver则为getter调用时的this值。

console.log(Reflect.set(obj, 'ES6', 'Reflect'), obj);

(3)Reflect.has(obj, name)

console.log(Reflect.has(obj, 'ES6')) //true

等同于name in obj。
(4)Reflect.deleteProperty(obj, name)
等同于delete obj[name]。

console.log(Reflect.deleteProperty(obj, 'ES6')) //true

(5)Reflect.construct(target, args)
等同于new target(…args) ,这提供了一种不使用new,来调用构造函数的方法。

function Person(a) {console.log(a);} 

  // Reflect.construct(target,args)	//在proxy内部使用,用来作为返回结果

(6)Reflect.getPrototypeOf(obj)
读取对象的__proto__属性,对应Object.getPrototypeOf(obj) 。

(7)Reflect.setPrototypeOf(obj, newProto)
设置对象的__proto__属性,对应Object.setPrototypeOf(obj, newProto) 。

(8)Reflect.apply(fun, thisArg, args)
等同于Function.prototype.apply.call(fun, thisArg, args) 。一般来说,如果要绑定一个函数的this对象,可以这样写fn.apply(obj, args) ,但是如果函数定义了自己的apply方法,就只能写成Function.prototype.apply.call(fn, obj, args) ,采用Reflect对象可以简化这种操作。

console.log( Function.prototype.apply.call(Math.floor, undefined, [1.75]))  //1
console.log(Reflect.apply(Math.floor, undefined, [1.75])) //1

另外,需要注意的是,Reflect.set() 、Reflect.defineProperty() 、Reflect.freeze() 、Reflect.seal()和Reflect.preventExtensions()返回一个布尔值,表示操作是否成功。它们对应的Object方法,失败时都会抛出错误。

失败时抛出错误
Object.defineProperty(obj, name, desc);
失败时返回false

Reflect.defineProperty(obj, name, desc);
上面代码中,Reflect.defineProperty方法的作用与Object.defineProperty是一样的,都是为对象定义一个属性。但是,Reflect.defineProperty方法失败时,不会抛出错误,只会返回false。

观察者模式
const queuedObservers = new Set();
//创建一个Set集合
const observe = fn => queuedObservers.add(fn);
//添加观察者回调到集合中
const observable = obj => new Proxy(obj, { set });
//Proxy监听
function set(target, key, value, receiver) {
	//调用Reflect的set方法来设置值
    const result = Reflect.set(target, key, value, receiver);
    //循环遍历监听队列
    queuedObservers.forEach(observer => observer());
    return result;
}
const person = observable({
    name: '张三',
    age: 20
});

function print() {
    console.log(`${person.name}, ${person.age}`)
}

observe(print);
person.name = '李四';
// 输出
// 李四, 20
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值