电力建设期刊网站经常维护吗,做房地产用什么网站好,wordpress多页面在一个页面,珠宝商城网站模板免费下载语法
target 要使用 Proxy 包装的目标对象#xff08;可以是任何类型的对象#xff0c;包括原生数组#xff0c;函数#xff0c;甚至另一个代理handler 一个通常以函数作为属性的对象#xff0c;用来定制拦截行为 const proxy new Proxy(target, handle)举个例子
s…语法
target 要使用 Proxy 包装的目标对象可以是任何类型的对象包括原生数组函数甚至另一个代理handler 一个通常以函数作为属性的对象用来定制拦截行为 const proxy new Proxy(target, handle)举个例子
script setup langts
const proxy {}
const obj new Proxy(proxy, {get(target, key, receiver) {console.log(get, target,key)// return 10return Reflect.get(target, key, receiver)},set(target, key, value, receiver) {console.log(set, key, value)// return 20return Reflect.set(target, key, value, receiver)}
})
const test1 () {obj.a 1}
const test2 () {console.log(obj.a)
}/scripttemplatedivbutton clicktest1test1/buttonbutton clicktest2test2/button/div
/template需要注意的是代理只会对proxy对象生效如上方的origin就没有任何效果
#Handler 对象常用的方法
方法描述handler.has()in 操作符的捕捉器。handler.get()属性读取操作的捕捉器。handler.set()属性设置操作的捕捉器。handler.deleteProperty()delete 操作符的捕捉器。handler.ownKeys()Object.getOwnPropertyNames 方法和 Object.getOwnPropertySymbols 方法的捕捉器。handler.apply()函数调用操作的捕捉器。handler.construct()new 操作符的捕捉器
#handler.get
get我们在上面例子已经体验过了现在详细介绍一下用于代理目标对象的属性读取操作
授受三个参数 get(target, propKey, ?receiver)
target 目标对象propkey 属性名receiver Proxy 实例本身
举个例子
const person {like: vuejs
}const obj new Proxy(person, {get: function(target, propKey) {if (propKey in target) {return target[propKey];} else {throw new ReferenceError(Prop name \ propKey \ does not exist.);}}
})obj.like // vuejs
obj.test // Uncaught ReferenceError: Prop name test does not exist.上面的代码表示在读取代理目标的值时如果有值则直接返回没有值就抛出一个自定义的错误
注意:
如果要访问的目标属性是不可写以及不可配置的则返回的值必须与该目标属性的值相同如果要访问的目标属性没有配置访问方法即get方法是undefined的则返回值必须为undefined
如下面的例子
const obj {};
Object.defineProperty(obj, a, { configurable: false, enumerable: false, value: 10, writable: false
})const p new Proxy(obj, {get: function(target, prop) {return 20;}
})p.a // Uncaught TypeError: get on proxy: property a is a read-only and non-configurable..#可撤消的Proxy
proxy有一个唯一的静态方法Proxy.revocable(target, handler)
Proxy.revocable()方法可以用来创建一个可撤销的代理对象
该方法的返回值是一个对象其结构为 {proxy: proxy, revoke: revoke}
proxy 表示新生成的代理对象本身和用一般方式 new Proxy(target, handler) 创建的代理对象没什么不同只是它可以被撤销掉。revoke 撤销方法调用的时候不需要加任何参数就可以撤销掉和它一起生成的那个代理对象。
该方法常用于完全封闭对目标对象的访问, 如下示例
const target { name: vuejs}
const {proxy, revoke} Proxy.revocable(target, handler)
proxy.name // 正常取值输出 vuejs
revoke() // 取值完成对proxy进行封闭撤消代理
proxy.name // TypeError: Revoked Proxy的应用场景
Proxy的应用范围很大简单举几个例子
#校验器 const target {_id: 1024,name: vuejs
}const validators { name(val) {return typeof val string;},_id(val) {return typeof val number val 1024;}
}const createValidator (target, validator) {return new Proxy(target, {_validator: validator,set(target, propkey, value, proxy){console.log(set, target, propkey, value, proxy)let validator this._validator[propkey](value)if(validator){return Reflect.set(target, propkey, value, proxy)}else {throw Error(Cannot set ${propkey} to ${value}. Invalid type.)}}})
}const proxy createValidator(target, validators)proxy.name vue-js.com // vue-js.com
proxy.name 10086 // Uncaught Error: Cannot set name to 10086. Invalid type.
proxy._id 1025 // 1025
proxy._id 22 // Uncaught Error: Cannot set _id to 22. Invalid type
#私有属性
在日常编写代码的过程中我们想定义一些私有属性通常是在团队中进行约定大家按照约定在变量名之前添加下划线 _ 或者其它格式来表明这是一个私有属性但我们不能保证他能真私‘私有化’下面使用Proxy轻松实现私有属性拦截
const target {_id: 1024,name: vuejs
}const proxy new Proxy(target, {get(target, propkey, proxy){if(propkey[0] _){throw Error(${propkey} is restricted)}return Reflect.get(target, propkey, proxy)},set(target, propkey, value, proxy){if(propkey[0] _){throw Error(${propkey} is restricted)}return Reflect.set(target, propkey, value, proxy)}
})proxy.name // vuejs
proxy._id // Uncaught Error: _id is restricted
proxy._id 1025 // Uncaught Error: _id is restrictedProxy 使用场景还有很多很多不再一一列举如果你需要在某一个动作的生命周期内做一些特定的处理那么Proxy 都是适合的 #开发中可能遇到的场景 增强操作的透明性可以在不修改目标对象本身的情况下为其增加额外的功能比如验证、日志记录、性能监控等。这使得代码更加模块化易于维护和扩展。
let target { message: Hello, world! };
let handler {get(target, prop, receiver) {console.log(Getting property ${prop});return Reflect.get(...arguments);},set(target, prop, value, receiver) {console.log(Setting property ${prop} to ${value});return Reflect.set(...arguments);}
};
let proxy new Proxy(target, handler);proxy.message; // 控制台输出: Getting property message
proxy.message Hi there!; // 控制台输出: Setting property message to Hi there!
2、属性访问控制允许你控制对对象属性的访问比如禁止某些属性被修改、只读访问、或者在访问不存在的属性时提供默认值等这对于构建安全或用户友好的API特别有用
const target { message: Read only };
const handler {set(target, prop, value, receiver) {if (prop message) {throw new Error(Message is read-only.);}return Reflect.set(...arguments);}
};
const proxy new Proxy(target, handler);console.log(proxy.message); // 输出: Read only
proxy.message New Value; // 抛出错误: Message is read-only.
3、数据绑定与自动更新在前端开发中尤其是与React、Vue等框架结合时可以利用Proxy监听对象属性变化自动触发UI更新实现数据双向绑定的效果。
class SimpleReactComponent extends React.Component {constructor(props) {super(props);this.state { count: 0 };this.handler {get(target, prop) {return target[prop];},set(target, prop, value) {target[prop] value;this.forceUpdate(); // 模拟React组件的更新return true;}};this.proxyState new Proxy(this.state, this.handler);}increment () {this.proxyState.count;};render() {return (divpCount: {this.proxyState.count}/pbutton onClick{this.increment}Increment/button/div);}
}ReactDOM.render(SimpleReactComponent /, document.getElementById(root));
4、资源管理与优化例如实现惰性加载lazy loading只有当属性第一次被访问时才去加载资源或者实现缓存机制减少重复的计算或网络请求。
function loadImage(url) {return new Promise((resolve, reject) {const img new Image();img.onload () resolve(img);img.onerror reject;img.src url;});
}class LazyImage {constructor(url) {this.url url;this.image null;}async get() {if (!this.image) {this.image await loadImage(this.url);}return this.image;}
}const proxyImage new Proxy(new LazyImage(path/to/image.jpg), {get(target, prop) {if (prop src) {return target.get().then(img img.src);}return Reflect.get(...arguments);}
});// 当需要时才真正加载图片
proxyImage.src.then(src console.log(Loaded image src:, src));
5、模拟对象或环境在测试、模拟数据或实现某些高级抽象时可以使用Proxy来创建具有特定行为的对象模拟数据库、文件系统或其他复杂系统的行为。
const db {users: [{ id: 1, name: Alice }, { id: 2, name: Bob }]
};const dbProxy new Proxy(db, {get(target, prop) {if (prop getUser) {return (id) {return target.users.find(user user.id id);};}return Reflect.get(...arguments);}
});console.log(dbProxy.getUser(1)); // 输出: { id: 1, name: Alice }
总之Proxy 提供了一种强大的工具用于控制对象的访问和操作它在很多方面都能帮助开发者编写更加灵活、高效和可控的代码。