JS Proxy 代理介绍

介绍

Proxy 是代理,可以完成对数据的处理,对构造函数的处理,对数据的验证,相当于在我们访问对象类型数据前添加了一层拦截,可以添加一些操作,可是是操作数据的,或者其他的,由自己定义。因为Proxy是构造函数,所以使用时需要new一下。

语法

let instance = new Proxy(target, handler);

参数说明:

1.target :需要使用Proxy包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。

2.handler: 一个对象,其属性是当执行一个操作时定义代理的行为的函数(可以理解为某种触发器)。

举个简单的栗子:

let obj1 = {
	name: "小明",
	age: 25
}

let obj2 = new Proxy(obj1, {
	get(target, key) {
		console.log('获取了对象的属性');
		return 'new-' + target[key];
	}
});

console.log(obj1.name);
console.log(obj2.name);

上面的例子中,首先创建了一个obj1对象,里面有name、age属性,然后将obj1作为目标对象使用Proxy将其包装起来,返回给obj2,因为obj2是一个Proxy实例,我们对其操作,都会被Proxy拦截
Proxy有两个参数,第一个是target,也就是我们传入的 obj1 对象,另一个则是handler,也就是我们传入的第二个参数,一个匿名对象。在handler中定义了一个名叫get的函数,当我们获取 obj1 的属性时,则会触发此函数。

上面的代码也可以这样写

  let obj = {
    name: "小蓝"
  };
  obj = new Proxy(obj, {
    get(target, key) {
      console.log('获取了getter属性');
      return target[key];
    }
  });
  console.log(obj .name);

先创建了一个obj对象,里面有name属性,然后我们使用Proxy将其包装起来,再返回给obj,此时的obj已经成为了一个Proxy实例,我们对其的操作,都会被Proxy拦截。


接下来试试使用set来拦截一些操作,并将get返回值更改

let xiaolan = {
	name: "小蓝",
	age: 15
};
xiaolan = new Proxy(xiaolan, {
	get(target, key) {
	    let result = target[key];
	    //如果是获取 年龄 属性,则添加 岁字
	    if (key === "age") result += "岁";
	    return result;
	},
	set(target, key, value) {
	    if (key === "age" && typeof value !== "number") {
		    throw Error("age字段必须为Number类型");
	    }
	    return Reflect.set(target, key, value);
	}
});
console.log(`我叫${xiaolan.name}  我今年${xiaolan.age}了`);
xiaolan.age = "aa";

上方案例中定义了 xiaolan 对象,其中有 agename 两个字段,我们在Proxy中的 get 拦截函数中添加了一个判断,如果是取 age 属性的值,则在后面添加 。在 set 拦截函数中判断了如果是更改 age 属性时,类型不是 Number则抛出错误。最后,正确的输出了我们想要的结果!

关于return Reflect.set(target, key, value); 这句代码, 

因为set函数必须返回一个boolean值,只有返回值为true时才表示修改成功,我们没有手动return,函数会自动返回undefined,undefined != true,所以报错是正常的,只需要手动在最后添加一句 return true即可!
但是,既然JS为我们提供了 Reflect ,那我们肯定是使用它滴,毕竟它和Proxy本来就是一起的,Proxy有的函数它都有

 

©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页