我可以将对象包装在代理和陷阱中并使用获取陷阱来防止"TypeError: Cannot read property 'b' of undefined"吗?



Javascript中,如果我尝试这样做:

var obj = {};
obj.z.c.f.d = 'foo';
`TypeError: Cannot read property 'c' of undefined`
at repl:1:7
at ContextifyScript.Script.runInThisContext (vm.js:50:33)
at REPLServer.defaultEval (repl.js:240:29)
at bound (domain.js:301:14)
at REPLServer.runBound [as eval] (domain.js:314:12)
at REPLServer.onLine (repl.js:442:10)
at emitOne (events.js:121:20)
at REPLServer.emit (events.js:211:7)
at REPLServer.Interface._onLine (readline.js:282:10)
at REPLServer.Interface._line (readline.js:631:8)

我不希望抛出此错误。

只需创建z.c.f并在其中添加d价值即可。

我们有一个遗留代码。

现在我想将此 obj 包装在代理中并能够捕获其方法。

如果未定义属性,则在此处创建一个对象,如果是非对象值;覆盖它。

我实现了这种方法,我可以简单地在代理的陷阱中使用这种方法,也许:

// setByString is not in Object.prototype. Only in my testObject
testObject.setByString('f.o.o', 1999); 
// this adds an f object and an o object inside, then an o value with 1999 to testObject. Merges deeply.

在这里,我的testObject应该只有数字、未定义、字符串、对象。

关键是我不能用代理做到这一点。

他们似乎没有我需要的东西。

无论如何,有没有办法做到这一点,如果代理不可能的话?

使用代理,您可以完全按照自己的要求进行操作:

var handler = {
get: function(target, name){
if(!(name in target))
target[name] = new Proxy({}, handler);;
return target[name];
}
};
var p = new Proxy({}, handler);

现在,尝试一下:

p.a.b.c = 45;//no TypeError here !!!

这是你所期望的吗?

试试这个

var testObject = {};
setByString(testObject, 'f.o.o', 1999); 
console.log(testObject);
function setByString(obj, props, val) {
var current = obj;
props.split('.').forEach((prop, index, self) => {
current[prop] = index !== self.length - 1 ? current[prop] || {} : val;
current = current[prop];
});
}

相关内容

最新更新