I have an object which may or may not have nested objects and properties, and I want to access them using a string. Here's an example...
var obj = {
inside: {
value: 10,
furtherInside: {
value: 100
}
}
// may contain other objects, properties, etc.
};
function getObjProperty(str) {
return eval("obj." + str);
}
getObjProperty("inside.value"); // returns 10
getObjProperty("inside.furtherInside.value"); // returns 100
...But I'd like a solution that doesn't use eval
. How can this be done without using eval ? I'm looking for the best/optimal/fastest solution.
How about something like
function getObjectProperty(obj, str) {
var props = str.split('.')
var result = obj;
for(var i = 0; i < props.length; i++)
result = result[props[i]];
return result;
}
This code assumes your strings are always valid and the object passed into getObjectProperty
has properties that nest to the level you target, but it avoids eval
. You could make it more robust with checks for undefined, but that may be overkill for what you need.
Test code, using your example:
var a = {
inside: {
value: 10,
furtherInside: {
value: 100
}
}
// may contain other objects, properties, etc.
};
console.log(getObjProperty(a, "inside.value")); // prints 10
console.log(getObjProperty(a, "inside.furtherInside.value")); // prints 100
You can use the brackets notation:
var obj = {
inside: {
value: 10,
furtherInside: {
value: 100
}
}
// may contain other objects, properties, etc.
};
alert(obj['inside']['furtherInside']['value']);
Then you may even use string properties like "my property":
var obj = {
"my property": 10
};
obj["my property"];
EDIT:
This is an approach (using brackets notation) to what you are asking for:
String.prototype.getVal = function(elem) {
var segments = this.split('.');
for (var i = 0; i < segments.length; i++) {
elem = elem[segments[i]];
}
return elem;
}
var obj = {
inside: {
value: 10,
furtherInside: {
value: 100
}
}
// may contain other objects, properties, etc.
};
console.log("inside.furtherInside.value".getVal(obj));
console.log("inside.value".getVal(obj));
http://jsfiddle.net/luismartin/kphtqd54
Since this method getVal() is being assigned to the String prototype, you may use it anywhere, and I think the implementation is pretty neat and fast. I hope this approach also helps getting rid of the negative vote :/
This is what I came up with, using some recursiveness...
function getObjProperty(obj, props) {
if (typeof props === 'string') {
if (props.indexOf('.') == -1) {
return obj[props];
} else {
props = props.split('.');
}
}
if (props.length == 1) {
return obj[props[0]];
} else if (props.length > 1) {
var top = props.shift();
return getObjProperty(obj[top], props);
} else {
return obj;
}
}
http://jsfiddle.net/0em2f6k6/ ...But it's not as fast as a simple for-loop. http://jsperf.com/0em2f6k6
Although not vanilla JavaScript, another possibility is to use lodash's _.get
function: https://lodash.com/docs#get .
_.get(obj, "inside.furtherInside.value");
It essentially does the same as @analytalica 's solution, except using a while
loop (see the baseGet
function in the lodash code ), but it also allows strings or arrays (using the toPath
function), and allows you to include a default.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.