多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
### 概述 `Proxy`用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种"元编程",即对编程语言进行编程。 `Proxy`可以理解成在目标对象前假设一个"拦截"层,外界对该对象的访问都必须通过这层拦截,因此提供了一种机制可以对外界的访问进行过滤和改写。 ```js let obj = new Proxy({}, { get: (target, key, receiver) => { console.log(`getting ${key}!`) return Reflect.get(target, key, receiver) }, set: (target, key, value, receiver) => { console.log(`setting ${key}`) return Reflect.set(target, key, value, receiver) } }) // obj.count = 1 // setting count // 1 // ++obj.count // getting count // setting count // 2 ``` ES6提供了`Proxy`构造函数,用于生成`Proxy`实例。 ```js let proxy = new Proxy(target, handler) ``` `new Proxy`表示生成一个`Proxy`实例,`target`参数表示所要拦截的目标对象,`handler`参数也是一个对象,用来定制拦截行为。 ```js const proxy = new Proxy({}, { get: (target, property) => { return 35 } }) ``` ### Proxy实例的方法 #### get() `get`方法用于拦截某个属性的读取操作 ```js let person = { name: '张三' } let proxy = new Proxy(person, { get: function (target, property) { if (property in target) { return target[property] } else { throw new ReferenceError("Property \"" + property + "\" does not exist.") } } }) proxy.name // '张三' proxy.age // 抛出错误 ``` #### set() `set`方法拥有拦截某个属性的赋值操作 ```js let validator = { set: function (obj, 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') } } obj[prop] = value } } let person = new Proxy({}, validator) person.age = 100 person.age // 100 person.age = 'young' // 报错 person.age = 300 // 报错 ``` #### apply() `apply`方法拦截函数的调用、`call`和`apply`操作 #### has() `has`方法用来拦截`HasProperty`操作,即判断对象是否具有某个属性时 #### construct() `construct`方法用于拦截`new`命令。 #### deleteProperty() `deleteProperty`方法用于拦截`delete`操作,如果这个方法抛出错误或返回`false`,当前属性就无法被`delete`命令删除。 #### defineProperty() `defineProperty`方法拦截了`Object.defineProperty`操作 #### getOwnpropertyDescriptor() `getOwnpropertyDescriptor`方法拦截`Object.getOwnPropertyDescriptor()`,返回一个属性描述对象或者`undefined` #### getPrototypeOf() `getPrototypeOf`方法主要用来拦截获取对象原型 #### isExtensible() `isExtensible`方法拦截`Object.isExtensible`操作 #### ownKeys() `ownKeys`方法用来拦截对象自身属性的读取操作 #### preventExtensions() #### setPrototypeOf() #### Proxy.revocable()