Reputation: 1333
I'm writing a function that will take in an object and modify a field within the object (could be a nested field). For instance, modifyObj(obj, 'nested.nested', 2) will essentially do obj.nested.nested = 2. The most straightforward way seems to be to use eval, but the consensus seems to be using eval is evil? http://jsfiddle.net/zntf6bfw/
function modifyObj(obj, field, val) {
var str = 'obj.' + field + '=' + val;
eval(str);
}
The alternative is to use regex to determine if the passed in field is nested, and if so, to use a loop to get a nested object and modify it (which will modify the overall object). However, this seems unnecessarily complicated, and would this count as a valid use case for eval?
function modifyObj2(obj, field, val) {
//if we are modifying a nested val
if (/\./g.test(field)) {
var arr = field.split('.'),
temp = obj;
//we want temp to be equal to the nested object holding the nested field to be modified and changing this will modify the passed in object
for (var i = 0; i < arr.length - 1; i++) {
temp = temp[arr[i]];
}
temp[arr.length - 1] = val;
}
//if we are modifying a non-nested val
else {
obj[field] = val;
};
}
Upvotes: 0
Views: 120
Reputation: 82277
Using eval is essentially always avoidable.
For a simple assignment like that (one nesting) just use a simple approach
function modifyObj(obj, field, val) {
obj[field] = val;
}
If field is in fact "prop[3].person.name" then you are going to want to use the regex approach or an object flattening approach such as
function flatten(obj){
var root = {};
(function tree(obj, index){
var suffix = toString.call(obj) == "[object Array]" ? "]" : "";
for(var key in obj){
if(!obj.hasOwnProperty(key))continue;
root[index+key+suffix] = obj[key];
if( toString.call(obj[key]) == "[object Array]" )tree(obj[key],index+key+suffix+"[");
if( toString.call(obj[key]) == "[object Object]" )tree(obj[key],index+key+suffix+".");
}
})(obj,"");
return root;
}
which allows for the use of complex strings as well. More on that here: https://stackoverflow.com/a/25370536/1026459
Upvotes: 0
Reputation: 179046
Is using eval appropriate when setting deeply nested properties in an object?
No.
It opens the script up to encoding bugs that could turn into security vulnerabilities.
The real question is what problem you're having that would lead you to believe that eval
was a reasonable solution. Consider the following code:
obj.foo.bar.baz.fizz.buzz = val;
your modifyObj
function:
modifyObj(obj, 'foo.bar.baz.fizz.buzz', val);
One of the two is concise, easy to read, easy to debug, easy to understand, and runs very quickly. The other is your modifyObj
function.
Upvotes: 1