概述

Reflect对象和Proxy对象一样,也是ES6为了操作对象而提供的API

Reflect对象的设计目的有以下几个:

1.将Object对象的一些明显属于语言内部的方法		(比如:Object.defineProperty)放到Reflect对象上。现阶段,某些方法同时在Object和Reflect对象上部署,未来的新方法将只在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上获取默认行为

1和2条的例子

// 旧写法
try{
	Object.defineProperty(target,property,attributes);
		// success
} catch(e){
		// failure
}


// 新写法
if(Reflect.defineProperty(target,property,attributes)){
	// success
}else{
	// failure
}

3条的例子

// 旧写法
console.log('assign' in Object);

// 新写法
console.log(Reflect.has(Object,'assign'));

4条的例子

const { 
	set ,
	get ,
	deleteProperty ,
	has
} = Reflect;

Proxy(target,{
	set : function(target,name,value,receiver){
		let success = set(target,name,value,receiver);
		if(success){
			log('property ' + name + ' on ' + target + ' set to ' + value);
		}
		return success;
	}
})

代码中,Proxy方法拦截target对象的属性赋值行为。

它采用Reflect.set方法将值赋给对象的属性,确保完成原有的行为,然后再部署额外的功能

let loggedObj = new Proxy(obj,{
	get(target,name){
		console.log('get',target,name);
		return get(target,name);
	},
	deleteProperty(target,name){
		console.log('delete',name);
		return deleteProperty(target,name);
	},
	has(target,name){
		console.log('has',name);
		return has(target,name);
	}
})

上面的代码中,m每一个Proxy对象的拦截操作(get,delete,has)内部都调用对应的Reflect方法,保证原生行为能正常运行,添加的工作就是将每一个操作输出一个日志

有了Reflect对象,很多操作更易读

// 旧写法
console.log(Function.prototype.apply.call(Math.floor,undefined,[1,75]));

// 新写法
console.log(Reflect.apply(Math.floor,undefined,[1,75]));
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐