菜菜子的代理和映射小记(说实话我也觉得不好理解.jpg)

157 阅读3分钟

一.Reflect反射

什么是反射?有啥作用?

reflect是一个内置对象,开发者可以通过调用来访问js的底层功能。

举个小例子:

const obj={
        a:1,
        b:2
    };
    Reflect.set(obj,'a',10);//通过这个方法可以改变obj对象里a的值
    console.log(Reflect.get(obj,'a'))//10等效于下面的console
    console.log(obj.a);//10
    
    
    --------我是分界线----------
    function method(a,b) {
    console.log('method',a,b);
}
Reflect.apply(method,null,[4,5])//等同于给a,b添加了两个值
const obj={
    a:1,
    b:2
}
Reflect.deleteProperty(obj,'a');
console.log(obj);//通过deleteProperty删除了a的字段和值,再打印obj.a为undefined。
    

二.Proxy代理

代理就是new一个虚拟化对象,然后就可以对目标对象的底层进行操作,但也只是转发而不会更改目标对象的属性。如果我们手动更改了目标对象的值,那么proxy的值也会随之更改。

let res={}
let proxy=new Proxy(res,{})//new一个proxy,内置代理的目标是res对象
proxy.name='zyy'//给res整一个name属性
console.log(proxy.name);
console.log(res.name);//出来的是zyy,注意只是转发过去了值,不是他自己定义的。
res.name='aa';
console.log(proxy.name);//再打印出来就是 aa了。

下面给大家更深的往下讲一下proxy的代理陷阱

1.set陷阱

let target={
    name:'target'
};
let proxy=new Proxy(target,{
    set(trapTarget,key,value,receiver){
        if(!trapTarget.hasOwnProperty(key)){
            if(isNaN(value)){
                throw new TypeError('属性必须是数字')
            }
        }
        return Reflect.set(trapTarget,key,value,receiver)
    }
    
})
   //添加一个新属性
    proxy.count=1;
    console.log(proxy.count);//因为是添加的值是数字,则不报错

    proxy.name='zyy'
    console.log(proxy.name);//直接赋值 'zyy'

    proxy.anthor='aaa'
    console.log(proxy.anthor); //因为添加的值不是数字则报错

案例里的四个参数: set(trapTarget,key,value,receiver)

  • trapTarget:接受代理的目标对象。
  • key:就是要写入的属性类型,在这里呢就依次对应的是target对象中的name属性,为字符串
  • value:被写入的值
  • recevier:操作发生的对象,比如通过proxy来添加属性,这个属性就是操作发生的对象 我们不仅能通过set来验证属性,还可以通过get来验证对象结构

2.get陷阱

let target={
};
let proxy=new Proxy(target,{
    get(trapTarget,key,receiver){
        if(!(key in receiver)){
            throw new TypeError("您的"+key+"属性不存在")
        }
        return Reflect.get(trapTarget,key,receiver);
    }
})
proxy.name='aa'
console.log(proxy.name);
console.log(proxy.bb);

其实以上代码的含义就是来判断对象里有没有这个字段名。如果有则输出,没有则抛出异常。

也可以将两个方法封装在一起,

let originObj = {
		employee:'jack'
	};
	
let optObj = new Proxy(originObj,{
	set(trapTarget,key,value,receiver){
		// 忽略原有属性
		if(!trapTarget.hasOwnProperty(key)){
			if(!isNaN(value)){ // 属性不能位数字
				throw new TypeError('属性不能为数字!')
		}
	}
	// 添加属性
	return Reflect.set(trapTarget,key,value,receiver);
	},
	get(trapTarget,key,receiver){
	     if(!(key in receiver)){
			throw new TypeError('属性'+key+'不存在');
		}
			
		return Reflect.get(trapTarget,key,receiver);
	}
	});

意思也很简单,一个是通过set来判断输入的值是不是目标对象里面有的,一个是通过get来判断新建的字段名是不是原来目标对象的。

唉,就到这吧,大家看着学,有哪里不对不全还请各位哥哥姐姐多多指点。小菜菜子再次鸣谢您的阅览和喜欢。点个赞!!!