lundi 25 mai 2015

JavaScript. Universal function to extract deep (probably non-existent) object property safely

I want to design a helper function which would try to execute passed as parameter deep property path and to return value extracted by it.

For example consider following code

var foo = {
        bar: [
            {
                baz: "someValue"
            }
        ]
};

function getByPath(path) {
    var val;
    try {
        val = eval(path);    
    } catch(e) {
        console.error(e);
    }
    return val;
}

var path1 = "foo.bar[2].baz";
var path2 = "foo.bar[0].baz";
var path3 = "foo.bar.baz";

console.log(path1 + ": " + getByPath(path1));
console.log(path2 + ": " + getByPath(path2));
console.log(path3 + ": " + getByPath(path3));
console.log("done.");

output

TypeError: Cannot read property 'baz' of undefined
    at eval (eval at getByPath (unknown source), <anonymous>:1:11)
    at getByPath (<anonymous>:13:15)
    at <anonymous>:24:28
    at Object.InjectedScript._evaluateOn (<anonymous>:895:140)
    at Object.InjectedScript._evaluateAndWrap (<anonymous>:828:34)
    at Object.InjectedScript.evaluate (<anonymous>:694:21)getByPath @ VM317:15(anonymous function) @ VM317:24InjectedScript._evaluateOn @ VM212:895InjectedScript._evaluateAndWrap @ VM212:828InjectedScript.evaluate @ VM212:694
VM317:24 foo.bar[2].baz: undefined
VM317:25 foo.bar[0].baz: someValue
VM317:26 foo.bar.baz: undefined
VM331:7 done.

So everything is good here: an existent property is extracted, undefined is returned for non-existent and an exception is caught and stacktrace is printed in case of attempt to read a property of undefined.

But this function is not reliable in case javascript code is compressed on a server because object/property names can be shortened by a compressor and path like "foo.bar[0].baz" won't exist anymore (proper one will look like "a.b[0].c").

Is there a good solution except playing with compressor settings?

Aucun commentaire:

Enregistrer un commentaire