Access grandchild of a variable (parent.child.grandchild) without dots and one pair of brackets
-
29-10-2019 - |
Question
I'm building a canvas-related class with a kind of conversion table. The conversion table can be edited by the user. (Isn't really relevant, but maybe you want to know why):
cLayout = function(option) {
//obtaining the canvas (el) here
this.setup = function(option) {
t=this.table;
for (var p in t)
{
el[t[p][0]] = option[p]||t[p][1]
}
}
this.setup(option)
}
cLayout.prototype.table = {
width:[['style']['width'],"100%"],
height:['style'['height'],"100%"],
bg:[['style']['backgroundColor'],""],
position:[['style']['position'],"absolute"],
left:['style'['left'],"0px"],
top:['style'['left'],"0px"]
}
Example:
var b = new cLayout({left:'10%',width:'90%'})
Real question:
Normally, I'd use el['style']['width']
to set el.style.width.
But I want to use el[something]
without the second pair of brackets: I want the property name to be completely variable (I also want to be able to set el['innerHTML']
). So, is there a way to get a grandchild by using a[b]
, without using a[b][c]
?
P.S. Of course, I don't want to use eval.
Solution
No it is not possible. If you have nested objects, you cannot just skip a level.
You could write a helper function though, which takes a string like "child.grandchild"
and sets the corresponding property:
function setProp(obj, prop, val) {
var parts = prop.split('.');
while(parts.length > 1) {
obj = obj[parts.shift()];
}
obj[parts.shift()] = val;
}
(You should also test whether a certain property is available.)
Then your code could look like:
var cLayout = function(option) {
//obtaining the canvas (el) here
this.setup = function(option) {
for(var p in this.table) {
setProp(el, this.table[p][0], option[p]||t[p][1]);
}
}
this.setup(option)
}
cLayout.prototype.table = {
width:['style.width',"100%"],
height:['style.height',"100%"],
//...
}