ES6(Reflect与Proxy)

Proxy 与 Reflect 是 ES6 为了操作对象引入的 API 。

Proxy 可以对目标对象的读取、函数调用等操作进行拦截,然后进行操作处理。它不直接操作对象,而是像代理模式,通过对象的代理对象进行操作,在进行这些操作时,可以添加一些需要的额外操作。

Reflect 可以用于获取目标对象的行为,它与 Object 类似,但是更易读,为操作对象提供了一种更优雅的方式。它的方与 Proxy 是对应的。

Proxy的基本用法

let pro = new Proxy(target,handler);

一个 Proxy 对象由两个部分组成: target 、 handler 。在通过 Proxy 构造函数生成实例对象时,需要提供这两个参数。target 即目标对象, handler是一个对象,里面定义的是对拦截对象所要进行的拦截方法。

案例一:

        <script type="text/javascript">
		let target = {
		        name: "zs",
		        age: 15
		    };
			
		let handler = {
		        get(target, name) {
		            console.log('getting:' + name);
		            return target[name]
		        }
		    };
			
		let pro = new Proxy(target,handler);
		console.log(pro.name);
	</script>

创建的target对象为所要拦截的对象,handler对象为拦截对象后执行的操作,这里get方法为读取操作,即用户想要读取pro中的属性时执行的拦截操作。最后创建一个Proxy实例,因为我设定的读取拦截操作为输出一个“getting:”+属性字符串,所以当我想读取pro中的属性时,拦截输出一个“getting:”+属性字符串。

案例二:

        <script type="text/javascript">
		let target = {
		        name: "zs",
		        age: 15
		    };
			
		let handler = {
		    };
			
		let pro = new Proxy(target,handler);
		console.log(pro.name);
	</script>

拦截操作对象handler为空,未对拦截对象设定拦截方法,该情况下pro直接指向原对象target,访问pro等同于访问target,所以结果为target中的结果。

案例三:

        <script type="text/javascript">
		let target = {
		        name: "zs",
		        age: 15
		    };
			
		let handler = {
		        get(target, name) {
		            console.log('getting:' + name);
		            return target[name]
		        }
		    };
			
		let pro = new Proxy(target,handler);
		let obj = Object.create(pro);
		console.log(pro.name);
	</script>

上述实例将pro作为obj的原型对象使用,虽然obj本身没有name这个属性,但是根据原型链,会在pro上读取到name属性,之后会执行相对应的拦截操作。

Proxy常用的拦截方法

  • get(target, propKey, receive)方法,用于拦截某个读取属性的操作,第一个参数为目标对象,第二个参数为属性名称,第三个属性为操作所针对的对象(可选参数)

案例四:

        <script type="text/javascript">
		let target = {
		        name: "zs",
		        age: 15
		    };
			
		let handler = {
		        get(target, propKey, receive){
						if(propKey in target){
							console.log("success");
						}else{
							console.log("error")
						}
						return Reflect.get(target, propKey, receive);
					}
		    };
			
		let pro = new Proxy(target,handler);
		console.log(pro.name);
		console.log(pro.sex);
	</script>

  • set(target, propKey, value, receiver),用于拦截某个属性的赋值操作,第一个参数为目标对象,第二个参数为属性名,第三个参数为属性值,第四个参数为操作行为所针对的对象(可选参数)

案例五:

        <script type="text/javascript">
		let target = {
		        name: "zs",
		        age: 15
		    };
			
		let handler = {
			get(target, propKey, receive){
					if(propKey in target){
						console.log("get success");
					}else{
						console.log("get error")
					}
					return Reflect.get(target, propKey, receive);
				},
				set(target, propKey, value, receiver){
					if(propKey=='age'){
						if(!Number.isInteger(value)){
							throw new TypeError('The age is not an integer');
						}else{
							console.log("set success");
						}
					}else{
						console.log("set success");
					}
					return Reflect.set(target, propKey, value, receiver);
				}
		    };
			
		let pro = new Proxy(target,handler);
		pro.age=30;
		pro.name='呵呵';
		console.log(pro.name);
		console.log(pro.age);
	</script>

  • has(target, propKey)用来拦截对象是否具有某个属性值的操作,第一个参数为目标对象,第二个参数为属性名

案例六:

        <script type="text/javascript">
		let target = {
		        name: "zs",
		        age: 15
		    };
			
		let handler = {
				has(target,proKey){
					console.log('handle has');
					return proKey in target;
				}
		    };
			
		let pro = new Proxy(target,handler);
		console.log('name' in pro);
		console.log('sex' in pro);
	</script>

Reflect的静态方法:

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)

Reflect对象的静态方法和Proxy对象的静态方法一一对应

菜鸟教程网址:https://www.runoob.com/w3cnote/es6-tutorial.html

发布了102 篇原创文章 · 获赞 64 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_42687829/article/details/100855556