我有一个对象,我想拦截对其任何属性的访问,如果它不存在则返回后备值。我尝试了以下实现,但由于某种原因,我返回了一个 Proxy 对象而不是后备值。
const isObject = obj => typeof obj === 'object';
const hasKey = (obj, key) => key in obj;
const isNullOrUndefined = obj => obj === null || obj === undefined;
const obj = {
keyOne: ''
};
const returnPropertyOnObject = (target, property) => {
if (isObject(target[property])) {
return safe(target[property])
}
return target[property];
}
function safe(obj) {
return new Proxy(obj, {
get: (target, property) => {
if (hasKey(target, property) && !isNullOrUndefined(target[property])) {
returnPropertyOnObject(target, property)
}
return new Proxy({}, {
get: function(target, property) {
return 'MISSING!!';
}
});;
}
});
}
const wrap = safe(obj);
console.log(wrap.notExists);
console.log(wrap.notExists.deep.nested.nested);
此外,我有时会在代理内部获取诸如 toJSON
或 toString
之类的属性。
我错过了什么?
最佳答案
一旦您从内部代理返回missing
,链就会被破坏,下一个点将返回空的undefined
。您必须从其 get
返回 stub 对象本身。要提供默认值,请覆盖 toPrimitive
:
undef = new Proxy({}, {
get(_, prop) {
// support some standard object methods, feel free to add more
if (prop === Symbol.toPrimitive)
return () => 'no such thing'
if (prop === 'toString')
return () => 'whatever you want'
if (prop === 'toJSON')
return () => 'whatever you want'
// if asked for a custom prop, return itself
return undef;
}
});
const safe = obj => new Proxy(obj, {
get(target, property) {
let v = target[property];
if (v === null || typeof v === 'undefined')
return undef;
if (typeof v === 'object')
return safe(v);
return v;
}
});
const wrap = safe({foo: {bar: 'hey'}});
console.log(wrap.foo.bar + "!");
console.log(wrap.notExists.xx.yy.zz + "!");
Symbol.toPrimitive is a symbol that specifies a function... called to convert an object to a corresponding primitive value.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toPrimitive
关于javascript - JS 代理拦截键和嵌套键不返回回退值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57715257/