I'm working on a little library that lets me do some basic key value coding with objects. Say I have the following object:
var data = { key1: "value1", key2: { nested1: 1, nested2: "wowza!" } };
And I have the following JavaScript function:
var setData = function(path, value) {
eval("data." + path + "= value;");
};
And in use:
setData("key1", "updated value1"); // data.key1 == "updated value1"
setData("key2.nested1", 99); // data.key2.nested1 == 99
This works, however I would like to accomplish the above without using eval
. Is this possible, or is eval
the best way to go?
EDIT:
NOTE it can be assumed the value you're setting exists, at least for path depth - 1. I'm more concerned about setting the value of an existing object.
I think this problem becomes easier and more natural to solve if you can be flexible in how you're specifying your path. If instead of doing something like
key2.nested1
you can do{key2:{nested1:{}}}
(object notation), it becomes fairly trivial:You're simply recursing into the 2nd arg of the
setData
call, until you find the value. Each time you recurse, you step down into thedata
tree at the specified point.This function can easily be modified to accept the dot notation you specified, too, but to me this is a cleaner and more natural approach (plus, String ops are slow).
Cheers
Recursion is what you need:
Inspired from @user1416920 I made this one :
What it does is pretty self explanatory ^^.
Yep, it's easy.
obj.prop = val
is the same asobj['prop'] = val
so you can rewrite setData as this:And that should do it.
However, I am not sure how much success you will have with the 3rd level (if that makes sense.) obj.prop.prop can't be referenced by obj['prop.prop'] and will instead have to be referenced by obj['prop']['prop'], so setData would have to be rewritten to take that into account. I'm not having much luck with that, though.
Edit: I have made one that (for me) sets it nested how you want, but no further than that. Unfortunately, if you are nesting deeper than your examples then I don't see a real reason to abandon
eval
. I have not done any benchmarks, but at some point the calculations will be more computationally expensive than eveneval
(which is pretty hard to accomplish.)This is what I came up with, which will set them at least 1 'level' deep; that is, it will work with
key2.nested1
but notkey2.nested1.i_love_nesting
, if that makes sense:Hope this helps. I might not have written this in the most efficient way, though...