10月初,Vue3.0预览版发布,其中一个重要改变就是数据绑定实现方式由 getter/setter 变为 Proxy。那么Proxy究竟是何方神圣,我们可以在哪些场景使用呢?
在MDN中的表述:Proxy 对象用于定义基本操作的自定义行为(如属性查找,赋值,枚举,函数调用等)。
从中可以看出,他的核心功能是 自定义行为
语法很简单
let p = new Proxy(target, handler);
可以代理的操作列表如下(点击链接到MDN查看详细使用说明):
handler.apply(target, thisArg, argumentsList) 拦截函数调用
handler.construct(target, args) 拦截new操作符
handler.defineProperty(target, property, descriptor
) 拦截对对象的
Object.defineProperty()
操作handler.deleteProperty(
target, property) 拦截delete属性
handler.get( target, property, receiver
) 拦截取值操作
handler.getOwnPropertyDescriptor()
handler.getPrototypeOf()
handler.has()
handler.isExtensible()
handler.ownKeys()
handler.preventExtensions()
handler.set(obj, prop, value)
拦截赋值操作
handler.setPrototypeOf()
通常我们这样使用代理类来操作,隐藏被代理的目标:
var target = { a:1, b:2 } //定义一个被代理的对象 target = new Proxy(target, handler); target.a = 10; //handler.set 函数会被调用
一个简单的应用场景,要设置一个人的年龄范围0-100:
var person = { age: 1 }; person = new Proxy( person, { set: function( target, prop, value ){ if (prop === 'age') { if( typeof value !== 'number' ) throw new Error('age value type error'); target[prop] = value < 0 ? 0 : ( value > 100 ? 100 : value ); } else { return Reflect.set(...arguments); } } }); console.log( person.age ); //1 person.age = -1; console.log( person.age ); // 0 person.age = 200; console.log( person.age ); // 100 person.age = 50; console.log( person.age ); // 50 person.age = 'some'; //age value type error
这样,代理的应用场景就显而易见了:
- 需要对默认行为进行干预的时候,用就对了!
- 需要完美地添加附加行为,同时不影响外部调用方式。