编辑
2022-02-23
开发
00
请注意,本文编写于 1184 天前,最后修改于 971 天前,其中某些信息可能已经过时。

目录

什么是Proxy
具体用法
Proxy可以设置的拦截
关于MVVM实现的猜想

什么是Proxy

Proxy本意是代理,这里可以翻译为代理器。用来在对象前面建立一层代理,在操作对象之前先经过代理进行拦截。

具体用法

示例

JavaScript
var a = {hello: '1'}; var obj = new Proxy(a, { get: function (target, propKey, receiver) { console.log(`getting ${propKey}!`); return Reflect.get(target, propKey, receiver); }, set: function (target, propKey, value, receiver) { console.log(`setting ${propKey}!`); return Reflect.set(target, propKey, value, receiver); } }); obj.a = 1; obj.hello = 2; console.log(a);

输出

setting a! setting hello! { hello: 2, a: 1 }

Proxy可以设置的拦截

  • get(target, propKey, receiver):拦截对象属性的读取,比如proxy.foo和proxy['foo']。
  • set(target, propKey, value, receiver):拦截对象属性的设置,比如proxy.foo = v或proxy['foo'] = v,返回一个布尔值。
  • has(target, propKey):拦截propKey in proxy的操作,返回一个布尔值。
  • deleteProperty(target, propKey):拦截delete proxy[propKey]的操作,返回一个布尔值。
  • ownKeys(target):拦截Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy)、Object.keys(proxy)、for...in循环,返回一个数组。该方法返回目标对象所有自身的属性的属性名,而Object.keys()的返回结果仅包括目标对象自身的可遍历属性。
  • getOwnPropertyDescriptor(target, propKey):拦截Object.getOwnPropertyDescriptor(proxy, propKey),返回属性的描述对象。
  • defineProperty(target, propKey, propDesc):拦截Object.defineProperty(proxy, propKey, propDesc)、Object.defineProperties(proxy, propDescs),返回一个布尔值。
  • preventExtensions(target):拦截Object.preventExtensions(proxy),返回一个布尔值。
  • getPrototypeOf(target):拦截Object.getPrototypeOf(proxy),返回一个对象。
  • isExtensible(target):拦截Object.isExtensible(proxy),返回一个布尔值。
  • setPrototypeOf(target, proto):拦截Object.setPrototypeOf(proxy, proto),返回一个布尔值。如果目标对象是函数,那么还有两种额外操作可以拦截。
  • apply(target, object, args):拦截 Proxy 实例作为函数调用的操作,比如proxy(...args)、proxy.call(object, ...args)、proxy.apply(...)。
  • construct(target, args):拦截 Proxy 实例作为构造函数调用的操作,比如new proxy(...args)

关于MVVM实现的猜想

function setProxy(app) { return new Proxy(app, { get(target, propKey, receiver) { if (propKey in target.$data) { return target.$data[propKey]; } if (propKey in target) { return Reflect.get(target, propKey, receiver); } throw new Error(`${propKey} is not found in object`); }, set(target, propKey, value, receiver) { if (propKey in target.$data) { target.$data[propKey] = value; target.element.innerHTML = target.render(); return true; } if (propKey in target) { return Reflect.set(target, propKey, value, receiver); } throw new Error(`${propKey} is not found in object`); } }) } function createApp(config) { var app = Object.assign({ el: '', template: '', components: {}, props: {}, data() { return {}; }, computed: {}, watch: {}, methods: {}, render() { var innerHTML = this.template; for (var i in this.$data) { innerHTML = innerHTML.replace(`{{ ${i} }}`, this.$data[i]); } return innerHTML; }, }, config); // 初始化元素 if (app.el == '') { throw new Error('el is required'); } app.element = document.querySelector(app.el); // 初始化data if (app.data) { app.$data = app.data(); } app.proxy = setProxy(app); return app.proxy; }
如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:谭三皮

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!