在JavaScript中,我想执行以下操作:
var pi = {};
pi[0]['*']['*'] = 1;
当然会抛出“无法读取属性'*'未定义”错误。显然我可以定义p [0] = {},但这有点痛苦,因为我将在不同的属性中粘贴许多不同的值,例如
pi[2]['O']['I-GENE'] = 1;
等。哈希的第一个键只是一个整数,所以我想我可以在顶层使用一个数组而不是一个哈希,然后默认初始化就像在这篇文章中一样:
但这并不能满足我对其他哈希值的默认初始化的需要。
看起来我想要做的就是遇到ECMAScript规范,它表明对象的未定义属性(这是JavaScript中的哈希)应该返回undefined,如下所述:
Set default value of javascript object attributes
有趣地包括危险的工作。
在我尝试使用这样的嵌套哈希的其他地方,我发现自己写了很多丑陋的代码,如下所示:
function incrementThreeGramCount(three_grams,category_minus_two,category_minus_one,category){
if(three_grams[category_minus_two] === undefined){
three_grams[category_minus_two] = {};
}
if(three_grams[category_minus_two][category_minus_one] === undefined){
three_grams[category_minus_two][category_minus_one] = {};
}
if(three_grams[category_minus_two][category_minus_one][category] === undefined){
three_grams[category_minus_two][category_minus_one][category] = 0;
}
three_grams[category_minus_two][category_minus_one][category]++;
}
我真的想在这里避免,或者至少找到一些通过原型方法添加Hash功能的好方法。然而,似乎因为JavaScript中的Hash和Object是同一个东西,我们不能真正使用JavaScript中的默认哈希行为而不影响很多其他事情......
也许我应该编写自己的Hash类......或者使用Prototypes:
http://prototypejs.org/doc/latest/language/Hash/
或其他人:
http://www.daveperrett.com/articles/2007/07/25/javascript-hash-class/
或mootools:
很多选择 - 希望我知道这里的最佳做法......答案 0 :(得分:2)
可以使用ES6 proxies完成此操作。您将使用get
处理程序在对象上定义代理。对具有get
值或对象没有自己的属性的键执行undefined
时,将其设置为使用相同get
处理程序的新代理并返回该新代理。
此外,这可以在不需要括号语法的情况下工作:
var obj = ...;
obj.a.b.c = 3;
不幸的是,作为ES6功能,他们的支持仅限于Firefox,并且可以在Chrome中启用实验标记。
答案 1 :(得分:1)
我会做那样的事情:
Object.prototype.get = function(v){
if(!this[v]){
this[v] = {}
}
return this[v];
}
然后,object["x"]["y"].z = 666
使用object.get("x").get("y").z = 666
。
答案 2 :(得分:0)
您可以编写一个简单的帮助程序来执行此操作。 e.g
function setWDef() {
var args = [].slice.call(arguments);
var obj = args.shift();
var _obj = obj;
var val = args.pop();
if (typeof obj !== "object") throw new TypeError("Expected first argument to be of type object");
for (var i = 0, j = args.length - 1; i < j; i++) {
var curr = args[i];
if (!_obj[curr]) _obj[curr] = {};
_obj = _obj[curr];
}
_obj[args.pop()] = val;
return obj;
}
现在只需使用函数
设置值var pi ={}
console.log (setWDef(pi,"0","*","a*",1)) //{"0": {"*": {"a*": 1}}}
继承人JSBin
上的演示答案 3 :(得分:0)
使用 drafted logical OR assignment operator ||=
,您可以执行以下操作:
const pi = [];
((((pi[0]||={})['*'])||={})['*'] = 1);
console.log(JSON.stringify({pi}));
输出:
{"pi":[{"*":{"*":1}}]}
您还可以将某些级别初始化为数组或定义默认属性值:
const pi = [];
((((((pi[0]||={})['*'])||=[])[3])||={'#':2})['*'] = 1);
console.log(JSON.stringify({pi}));
输出:
{"pi":[{"*":[null,null,null,{"#":2,"*":1}]}]}