handler.get()
方法用于拦截对象属性的读取操作。
const proxy = new Proxy(target, {get: function (target, property, receiver) {// do something},});
参数 | 说明 | 类型 |
---|---|---|
target | 目标对象 | object |
property | 被获取的属性名 | string |
receiver | Proxy 或者继承 Proxy 的对象 | object |
该方法会拦截目标对象的以下操作:
proxy[foo]
和 proxy.bar
Object.create(proxy)[foo]
Reflect.get()
如果违背了以下的约束,proxy
会抛出 TypeError:
get
方法是 undefined
的,则返回值必须为 undefined
以下代码演示如何拦截属性值的读取操作:
const proxy = new Proxy({},{get: function (target, prop, receiver) {console.log('Called:' + prop);return 10;},});console.log(proxy.foo);// foo
以下是违反约束的情况:
const foo = {};Object.defineProperty(foo, 'a', {configurable: false,enumerable: false,value: 10,writable: false,});const proxy = new Proxy(foo, {get: function (target, prop) {return 'b';},});console.log(proxy.a);// Uncaugt TypeError: 'get' on proxy: property 'a' is a read-only and non-configurable data// property on the proxy target but the proxy did not return its actual value
const createArr = function (...elements) {const handler = {get(target, propKey, receiver) {const index = Number(propKey);if (index < 0) {propKey = String(target.length + index);}return Reflect.get(target, propKey, receiver);},};let target = [];target.push(...elements);return new Proxy(target, handler);};const arr = createArr('a', 'b', 'c');console.log(arr[-1]);// c
const pipe = function (value) {const stack = [];const proxy = new Proxy({},{get: function (pipeObject, fnName) {if (fnName === 'get') {return stack.reduce(function (val, fn) {return fn(val);}, value);}stack.push(window[fnName]);return proxy;},});return proxy;};const double = (x) => x * 2;const pow = (x) => x * x;const reverseInt = (x) => x.toString().split('').reverse().join('') | 0;pipe(3).double.pow.reverseInt.get;// 63
const dom = new Proxy({},{get(target, property) {return function (attrs = {}, ...children) {const ele = document.createElement(property);for (let prop of Object.keys(attrs)) {ele.setAttribute(prop, attrs[prop]);}for (let child of children) {if (typeof child === 'string') {child = document.createTextNode(child);}ele.appendChild(child);}return ele;};},});const el = dom.div({},'Hello, my name is ',dom.a({ href: '//example.com' }, 'Mark'),'. I like:',dom.ul({}, dom.li({}, 'The web'), dom.li({}, 'Food'), dom.li({}, "…actually that's it")));document.body.appendChild(el);