Here I offer more ways, which seem faster many here:
Option 1: Split string on . or [ or ] or ' or ", reverse it, skip empty items.
function getValue(path, origin) {
if (origin === void 0 || origin === null) origin = self ? self : this;
if (typeof path !== 'string') path = '' + path;
var parts = path.split(/\[|\]|\.|'|"/g).reverse(), name; // (why reverse? because it's usually faster to pop off the end of an array)
while (parts.length) { name=parts.pop(); if (name) origin=origin[name]; }
return origin;
}
Option 2 (fastest of all, except eval
): Low level character scan (no regex/split/etc, just a quick char scan).
Note: This one does not support quotes for indexes.
function getValue(path, origin) {
if (origin === void 0 || origin === null) origin = self ? self : this;
if (typeof path !== 'string') path = '' + path;
var c = '', pc, i = 0, n = path.length, name = '';
if (n) while (i<=n) ((c = path[i++]) == '.' || c == '[' || c == ']' || c == void 0) ? (name?(origin = origin[name], name = ''):(pc=='.'||pc=='['||pc==']'&&c==']'?i=n+2:void 0),pc=c) : name += c;
if (i==n+2) throw "Invalid path: "+path;
return origin;
} // (around 1,000,000+/- ops/sec)
Option 3: (new: option 2 expanded to support quotes - a bit slower, but still fast)
function getValue(path, origin) {
if (origin === void 0 || origin === null) origin = self ? self : this;
if (typeof path !== 'string') path = '' + path;
var c, pc, i = 0, n = path.length, name = '', q;
while (i<=n)
((c = path[i++]) == '.' || c == '[' || c == ']' || c == "'" || c == '"' || c == void 0) ? (c==q&&path[i]==']'?q='':q?name+=c:name?(origin?origin=origin[name]:i=n+2,name='') : (pc=='['&&(c=='"'||c=="'")?q=c:pc=='.'||pc=='['||pc==']'&&c==']'||pc=='"'||pc=="'"?i=n+2:void 0), pc=c) : name += c;
if (i==n+2 || name) throw "Invalid path: "+path;
return origin;
}
JSPerf: http://jsperf.com/ways-to-dereference-a-delimited-property-string/3
"eval(...)" is still king though (performance wise that is). If you have property paths directly under your control, there shouldn't be any issues with using 'eval' (especially if speed is desired). If pulling property paths "over the wire" (on the line!? lol :P), then yes, use something else to be safe. Only an idiot would say to never use "eval" at all, as there ARE good reasons when to use it. Also, "It is used in Doug Crockford's JSON parser." If the input is safe, then no problems at all. Use the right tool for the right job, that's it.
var part1name = someObject.part1name;
` – 3nigma Jun 27 '11 at 10:29