问题描述
我试图复制 Python 的 defaultdict
的基本用法,特别是如果键不存在,则假定数组作为值的事实。
这是能够做到的
mydict.hello.push(1)
即使 hello
不存在。
为此我尝试使用 Proxy,但我想我不明白它的实际工作原理:
let defaultDict = new Proxy({},{
set: (target,name) => {
if (target.name === undefined) {
target.name = []
}
}
})
let a = defaultDict
a.hello.push(1)
a.hello.push(2)
a.world.push(1)
console.log(a)
错误 Cannot read property 'push' of undefined
正是我想要避免的。
应该以某种方式实例化 defaultDict
吗?
解决方法
有几个问题:
- 您声明了一个 setter (
set
),但您想要的是一个 getter。当您执行a.hello
时,您将获得价值,然后推送给它 - 在JS中,当你想使用一个变量作为属性名时,你需要使用括号表示法:
target[name]
,因为target.name
在字面上指的是一个名为“name”的prop - 既然是getter,还需要返回值
这是一个工作示例:
const a = new Proxy({},{
get: (target,name) => {
if (target[name] === undefined) {
target[name] = [];
}
return target[name];
}
});
a.hello.push(1);
a.hello.push(2);
a.world.push(1);
console.log(a);
在这里,您会看到对象也有一个属性 toJSON
。那是因为 StackSnippet 在其上查找 toJSON
道具,该值不存在,因此您的代理创建了它。这是需要注意的副作用之一。