es6-Proxy、Reflect

Proxy

拦截操作、修改对象的默认行为。

// target参数表示要拦截的目标对象,handler参数处理拦截行为。
var proxy = new Proxy(target,handler);
var user = {
	name:'admin',
	age:'22'
}
1.get()
var proxy = new Proxy(user,{
	get(target,property) {
		if(property in target){
			return target[property];
		}else{
			throw new ReferenceError("Property \ "+property+" \" does not exist");
		}
	}
});
proxy.name;              //"admin"
proxy.pass;               // 抛出错误
// 如果没有拦截操作,访问不存在的属性会返回undefined。
// 实现数组读取负数索引
function createArray(...item){
	let handler = {
		get(target,prop,receiver) {
			let index = Number(prop);
			if(index < 0){
				prop = String(target.length+index);
			}
			return Reflect.get(target,prop,receiver);
		}
	}
	let target = [];
	target.push(...item);
	return new Proxy(target,handler);
}
let arr = createArray(3,4,5);
arr[2];           //5
arr[-1];          //5
2.set()
利用set方法,可以数据绑定,即对象发生变化时,会自动更新DOM。
let proxy = new Proxy(user,{
	set(target,prop,value) {
		if(prop === 'age'){
			if(!Number.isInteger(value)){
				throw new TypeError('The age is not an integer');
			}
			if(value>200){
				throw new RangeError("The age seems invalid");
			}
		}
		target[prop] = value;
	}
});
proxy.age;           //22
proxy.age = "hello";           //抛处一个错误,‘The age is not an integer’
proxy.age = 300;              //抛处一个错误,‘The age seems invalid’
3.可拦截操作过滤掉私有属性,以‘_’为前缀的属性。
> has()/拦截 in 操作符
var handler = {
	has(target,key) {
		if(key[0] === '_'){
			return false;
		}
		return key in target;
	}
}
var target = {_name:'admin',name:'xiao li'};
var proxy = new Proxy(target,handler);
'_name' in proxy;            //false;
'_name' in target;             //true
> enumerate()/拦截for...in循环                                 **未支持
var handler = {
	enumerate(target) {
		return Object.keys(target).filter(key=>key[0]!=='_')[Symbol.iterator]();
	}
}
var target = {name:'admin',_name:'System',_age:'34'};
var proxy = new Proxy(target,handler);
for(let key in proxy){
	console.log(key);
}             //name
> getPrototypeOf()
拦截以下操作:
	Object.getPrototypeOf();
	Object.prototype.__proto__;
	Object.prototype.isPrototypeOf();
	Object.getPrototypeOf();
	Reflect.getPrototypeOf();
	instanceOf运算符

Proxy.revocable()
返回一个可取消的Proxy实例。

let target = {};
let handler = {};
let {proxy,revoke} = Proxy.revocable(target,handler);
proxy.name = "admin";
proxy.name;         //"admin"

revoke();
proxy.name;        // 抛处错误,‘has been revoked’

Proxy是针对Proxy实例进行操作的,访问原对象不会拦截操作。
Proxy支持的拦截操作的方法和Reflect对象的方法对应。

Reflect

为操作对象提供的新API。
特点:

1.将Object对象上属于语言层面的方法放到Reflect对象上。
2.修改了Object对象某些方法的返回结果。
3.让Object一些命令式的操作都变成函数行为,
4.Reflect对象的方法与Proxy对象的方法一一对应。

Reflect对象的方法。

1、
var obj = {
	name:'hello'
}
Reflect.getOwnPropertyDescriptor(obj,"name");
/**
	{	configurable:true
		enumerable:true
		value:"hello"
		writable:true
	}
**/
Reflect.defineProperty(obj,"name",{
	enumerable:false
});                           //true
Reflect.getOwnPropertyNames	(obj);             //未支持,
Object.getOwnPropertyNames(obj);              //"name"
2、某些对应Object的方法,替代
Reflect.has(obj,name);         === name in obj
Reflect.deleteProperty(obj,name);          === delete obj[name]
Reflect.construct(target,args);          === new target(...args);
对象方法参数描述
Reflect.getOwnPropertyDescriptortarget,name获取目标对象的描述属性
.definePropertytarget,name,desc定义属性的描述对象
.getOwnPropertyNamestarget**未支持
.getPrototypeOftarget获取对象的原型对象
.setPrototypeOftarget,prototype
.deletePropertytarget,name删除对象中的属性
.enumeratetarget**未支持
.freezetarget冻结对象,防止修改
.sealtarget密封对象,防止删除
.preventExtensionstarget防止对象的扩展
.isFrozentarget
.isSealedtarget
.isExtensibletarget
.isPrototypeOftarget检测目标对象是存在于另一个对象的原型链上
obj.propertyIsEnumerablename该属性是否可枚举
.hastarget,name是否拥有该属性,返回Boolean
.hasOwntarget,name**未支持
obj.hasOwnPropertyname对象是否包含该属性
.keystarget**未支持
.ownKeystarget返回对象的属性名
.gettarget,name,receiver
.settarget,name,value,receiver
.applytarget,thisArg,args
.constructtarget,args
.valueOftarget返回对象的原始属性
.toString
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

heroboyluck

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值