Test for existence of nested JavaScript object key











up vote
490
down vote

favorite
207












If I have a reference to an object:



var test = {};


that will potentially (but not immediately) have nested objects, something like:



{level1: {level2: {level3: "level3"}}};


What is the best way to test for the existence of keys in the most deeply nested objects?



alert(test.level1); yields undefined, but alert(test.level1.level2.level3); fails.



I’m currently doing something like this:



if(test.level1 && test.level1.level2 && test.level1.level2.level3) {
alert(test.level1.level2.level3);
}


but I was wondering if there’s a better way.










share|improve this question




















  • 1




    you might want to check a tangentially related question that was asked recently stackoverflow.com/questions/2525943/…
    – Anurag
    Apr 13 '10 at 16:21












  • See also stackoverflow.com/questions/10918488/…
    – James McMahon
    Dec 21 '12 at 15:38










  • A couple of propositions there : stackoverflow.com/a/18381564/1636522
    – leaf
    Sep 7 '13 at 7:27










  • Your current approach has a potential issue if level3 property is a false, in that case, even if the property exist will retur nfalse have a look at this example please jsfiddle.net/maz9bLjx
    – GibboK
    Jul 11 '15 at 6:18






  • 7




    simply you can use try catch also
    – Raghavendra
    Aug 12 '15 at 12:07

















up vote
490
down vote

favorite
207












If I have a reference to an object:



var test = {};


that will potentially (but not immediately) have nested objects, something like:



{level1: {level2: {level3: "level3"}}};


What is the best way to test for the existence of keys in the most deeply nested objects?



alert(test.level1); yields undefined, but alert(test.level1.level2.level3); fails.



I’m currently doing something like this:



if(test.level1 && test.level1.level2 && test.level1.level2.level3) {
alert(test.level1.level2.level3);
}


but I was wondering if there’s a better way.










share|improve this question




















  • 1




    you might want to check a tangentially related question that was asked recently stackoverflow.com/questions/2525943/…
    – Anurag
    Apr 13 '10 at 16:21












  • See also stackoverflow.com/questions/10918488/…
    – James McMahon
    Dec 21 '12 at 15:38










  • A couple of propositions there : stackoverflow.com/a/18381564/1636522
    – leaf
    Sep 7 '13 at 7:27










  • Your current approach has a potential issue if level3 property is a false, in that case, even if the property exist will retur nfalse have a look at this example please jsfiddle.net/maz9bLjx
    – GibboK
    Jul 11 '15 at 6:18






  • 7




    simply you can use try catch also
    – Raghavendra
    Aug 12 '15 at 12:07















up vote
490
down vote

favorite
207









up vote
490
down vote

favorite
207






207





If I have a reference to an object:



var test = {};


that will potentially (but not immediately) have nested objects, something like:



{level1: {level2: {level3: "level3"}}};


What is the best way to test for the existence of keys in the most deeply nested objects?



alert(test.level1); yields undefined, but alert(test.level1.level2.level3); fails.



I’m currently doing something like this:



if(test.level1 && test.level1.level2 && test.level1.level2.level3) {
alert(test.level1.level2.level3);
}


but I was wondering if there’s a better way.










share|improve this question















If I have a reference to an object:



var test = {};


that will potentially (but not immediately) have nested objects, something like:



{level1: {level2: {level3: "level3"}}};


What is the best way to test for the existence of keys in the most deeply nested objects?



alert(test.level1); yields undefined, but alert(test.level1.level2.level3); fails.



I’m currently doing something like this:



if(test.level1 && test.level1.level2 && test.level1.level2.level3) {
alert(test.level1.level2.level3);
}


but I was wondering if there’s a better way.







javascript object nested






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 14 at 14:31









Xufox

9,90562848




9,90562848










asked Apr 13 '10 at 15:47









user113716

258k55399416




258k55399416








  • 1




    you might want to check a tangentially related question that was asked recently stackoverflow.com/questions/2525943/…
    – Anurag
    Apr 13 '10 at 16:21












  • See also stackoverflow.com/questions/10918488/…
    – James McMahon
    Dec 21 '12 at 15:38










  • A couple of propositions there : stackoverflow.com/a/18381564/1636522
    – leaf
    Sep 7 '13 at 7:27










  • Your current approach has a potential issue if level3 property is a false, in that case, even if the property exist will retur nfalse have a look at this example please jsfiddle.net/maz9bLjx
    – GibboK
    Jul 11 '15 at 6:18






  • 7




    simply you can use try catch also
    – Raghavendra
    Aug 12 '15 at 12:07
















  • 1




    you might want to check a tangentially related question that was asked recently stackoverflow.com/questions/2525943/…
    – Anurag
    Apr 13 '10 at 16:21












  • See also stackoverflow.com/questions/10918488/…
    – James McMahon
    Dec 21 '12 at 15:38










  • A couple of propositions there : stackoverflow.com/a/18381564/1636522
    – leaf
    Sep 7 '13 at 7:27










  • Your current approach has a potential issue if level3 property is a false, in that case, even if the property exist will retur nfalse have a look at this example please jsfiddle.net/maz9bLjx
    – GibboK
    Jul 11 '15 at 6:18






  • 7




    simply you can use try catch also
    – Raghavendra
    Aug 12 '15 at 12:07










1




1




you might want to check a tangentially related question that was asked recently stackoverflow.com/questions/2525943/…
– Anurag
Apr 13 '10 at 16:21






you might want to check a tangentially related question that was asked recently stackoverflow.com/questions/2525943/…
– Anurag
Apr 13 '10 at 16:21














See also stackoverflow.com/questions/10918488/…
– James McMahon
Dec 21 '12 at 15:38




See also stackoverflow.com/questions/10918488/…
– James McMahon
Dec 21 '12 at 15:38












A couple of propositions there : stackoverflow.com/a/18381564/1636522
– leaf
Sep 7 '13 at 7:27




A couple of propositions there : stackoverflow.com/a/18381564/1636522
– leaf
Sep 7 '13 at 7:27












Your current approach has a potential issue if level3 property is a false, in that case, even if the property exist will retur nfalse have a look at this example please jsfiddle.net/maz9bLjx
– GibboK
Jul 11 '15 at 6:18




Your current approach has a potential issue if level3 property is a false, in that case, even if the property exist will retur nfalse have a look at this example please jsfiddle.net/maz9bLjx
– GibboK
Jul 11 '15 at 6:18




7




7




simply you can use try catch also
– Raghavendra
Aug 12 '15 at 12:07






simply you can use try catch also
– Raghavendra
Aug 12 '15 at 12:07














48 Answers
48






active

oldest

votes













1 2
next











up vote
313
down vote



accepted
+500










You have to do it step by step if you don't want a TypeError, because if one of the members is null or undefined, and you try to access a member an exception will be thrown.



You can either simply catch the exception, or make a function to test the existence of multiple levels, something like this:



function checkNested(obj /*, level1, level2, ... levelN*/) {
var args = Array.prototype.slice.call(arguments, 1);

for (var i = 0; i < args.length; i++) {
if (!obj || !obj.hasOwnProperty(args[i])) {
return false;
}
obj = obj[args[i]];
}
return true;
}

var test = {level1:{level2:{level3:'level3'}} };

checkNested(test, 'level1', 'level2', 'level3'); // true
checkNested(test, 'level1', 'level2', 'foo'); // false





share|improve this answer



















  • 4




    arguments is not actually an array. Array.prototype.slice.call(arguments) converts it to a formal array. Learn
    – deefour
    Nov 10 '12 at 1:00








  • 22




    this'd be a lot more efficient to do var obj = arguments[0]; and start from var i = 1 instead of copying the arguments object
    – Claudiu
    Oct 31 '13 at 19:45








  • 17




    FYI, you can also use _.get() from lodash for this lodash.com/docs#get
    – vasa
    Oct 12 '15 at 21:19






  • 3




    In ES6 the args variable declaration can be removed and and ...args can be used as the second argument for the checkNested method. developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
    – Vernon
    Dec 28 '16 at 15:49






  • 2




    This is a very unmaintainable. If any property keys change (they will), all devs on the project would have to 'string search' the entire codebase. This isn't really a solution to the problem, as it introduces a much bigger problem
    – Drenai
    Jan 14 at 11:20




















up vote
306
down vote













Here is a pattern I picked up from Oliver Steele:



var level3 = (((test || {}).level1 || {}).level2 || {}).level3;
alert( level3 );


In fact that whole article is a discussion of how you can do this in javascript. He settles on using the above syntax (which isn't that hard to read once you get used to it) as an idiom.






share|improve this answer



















  • 8




    @wared I think it is interesting mostly for how concise it is. There is a detailed discussion of the performance characteristics in the linked post. Yes it always does all the tests, but it avoids creating temp vars, and you can alias {} to a var if you want to prevent the overhead of creating a new empty object each time. In 99% of cases I would not expect speed to matter, and in cases where it does there is no substitute for profiling.
    – Gabe Moothart
    Sep 5 '13 at 18:13








  • 9




    @MuhammadUmer No, the point of (test || {}) is that if test is undefined, then you're doing ({}.level1 || {}). Of course, {}.level1 is undefined, so that means you're doing {}.level2, and so on.
    – Joshua Taylor
    Apr 28 '15 at 16:06






  • 13




    you said "which isn't that hard to read once you get used to it". Well, these are signs you know already this is a mess. Then why suggest this solution? It is prone to typos and gives absolutely nothing to readability. Just look it! If i have to write an ugly line, it should asswell be readable; so i'm going to just stick with if(test.level1 && test.level1.level2 && test.level1.level2.level3)
    – Sharky
    Sep 30 '16 at 9:16








  • 6




    Unless I'm missing something, this won't work for boolean end-properties that might be false... sadly. Otherwise I love this idiom.
    – T3db0t
    Nov 17 '16 at 20:01






  • 5




    This is both hard to read and hard to type.
    – pootzko
    Jun 29 '17 at 9:36


















up vote
207
down vote













Update



Looks like lodash has added _.get for all your nested property getting needs.



_.get(countries, 'greece.sparta.playwright')


https://lodash.com/docs#get





Previous answer



lodash users may enjoy lodash.contrib which has a couple methods that mitigate this problem.



getPath



Signature: _.getPath(obj:Object, ks:String|Array)



Gets the value at any depth in a nested object based on the path described by
the keys given. Keys may be given as an array or as a dot-separated string.
Returns undefined if the path cannot be reached.



var countries = {
greece: {
athens: {
playwright: "Sophocles"
}
}
}
};

_.getPath(countries, "greece.athens.playwright");
// => "Sophocles"

_.getPath(countries, "greece.sparta.playwright");
// => undefined

_.getPath(countries, ["greece", "athens", "playwright"]);
// => "Sophocles"

_.getPath(countries, ["greece", "sparta", "playwright"]);
// => undefined





share|improve this answer























  • Lodash really needs a _.isPathDefined(obj, pathString) method.
    – Matthew Payne
    Jan 9 '15 at 16:34










  • @MatthewPayne It'd be nice perhaps, but it really isn't necessary. You could do it yourself really easily function isPathDefined(object, path) { return typeof _.getPath(object, path) !== 'undefined'; }
    – Thor84no
    May 12 '15 at 11:33








  • 11




    Lodash has this same functionality itself: _.get(countries, 'greece.sparta.playwright', 'default'); // → 'default' _.has(countries, 'greece.spart.playwright') // → false
    – Tom
    May 15 '15 at 18:23












  • @Tom thanks. Really glad they include that by default now.
    – Austin Pray
    May 15 '15 at 22:56










  • even better would be _.result
    – Shishir Arora
    Aug 29 '15 at 8:50


















up vote
141
down vote













I have done performance tests (thank you cdMinix for adding lodash) on some of the suggestions proposed to this question with the results listed below.




Disclaimer #1 Turning strings into references is unnecessary meta-programming and probably best avoided. Don't lose track of your references to begin with. Read more from this answer to a similar question.



Disclaimer #2 We are talking about millions of operations per millisecond here. It is very unlikely any of these would make much difference in most use cases. Choose whichever makes the most sense knowing the limitations of each. For me I would go with something like reduce out of convenience.




Object Wrap (by Oliver Steele) – 34 % – fastest



var r1 = (((test || {}).level1 || {}).level2 || {}).level3;
var r2 = (((test || {}).level1 || {}).level2 || {}).foo;


Original solution (suggested in question) – 45%



var r1 = test.level1 && test.level1.level2 && test.level1.level2.level3;
var r2 = test.level1 && test.level1.level2 && test.level1.level2.foo;


checkNested – 50%



function checkNested(obj) {
for (var i = 1; i < arguments.length; i++) {
if (!obj.hasOwnProperty(arguments[i])) {
return false;
}
obj = obj[arguments[i]];
}
return true;
}


get_if_exist – 52%



function get_if_exist(str) {
try { return eval(str) }
catch(e) { return undefined }
}


validChain – 54%



function validChain( object, ...keys ) {
return keys.reduce( ( a, b ) => ( a || { } )[ b ], object ) !== undefined;
}


objHasKeys – 63%



function objHasKeys(obj, keys) {
var next = keys.shift();
return obj[next] && (! keys.length || objHasKeys(obj[next], keys));
}


nestedPropertyExists – 69%



function nestedPropertyExists(obj, props) {
var prop = props.shift();
return prop === undefined ? true : obj.hasOwnProperty(prop) ? nestedPropertyExists(obj[prop], props) : false;
}


_.get – 72%



deeptest – 86%



function deeptest(target, s){
s= s.split('.')
var obj= target[s.shift()];
while(obj && s.length) obj= obj[s.shift()];
return obj;
}


sad clowns – 100% – slowest



var o = function(obj) { return obj || {} };

var r1 = o(o(o(o(test).level1).level2).level3);
var r2 = o(o(o(o(test).level1).level2).foo);





share|improve this answer



















  • 12




    it should be noted that the more % a test has - the SLOWER it is
    – avalanche1
    Feb 3 '17 at 9:12






  • 1




    what about lodash _.get() ? how performant is it comparing to those answers?
    – beniutek
    May 31 '17 at 14:07






  • 3




    Tests with _.get() - jsben.ch/7aJgK
    – cdMinix
    Jun 27 '17 at 7:47








  • 1




    Each method of these is slower or faster than other ones depending on situation. If all keys are found then "Object Wrap" could be fastest, but if one of the keys is not found then "Native solution/Original solution" could be faster.
    – evilReiko
    Aug 28 '17 at 6:55






  • 1




    @evilReiko Any method will be slower if no keys are found but in proportion to each other it's still pretty much the same. However, you are right – this is more of an intellectual exercise than anything else. We are talking about a million iterations per millisecond here. I see no use case where it would make much difference. Me personally I would go for reduce or try/catch out of convenience.
    – unitario
    Aug 30 '17 at 6:36


















up vote
41
down vote













You can read an object property at any depth, if you handle the name like a string: 't.level1.level2.level3'.



window.t={level1:{level2:{level3: 'level3'}}};

function deeptest(s){
s= s.split('.')
var obj= window[s.shift()];
while(obj && s.length) obj= obj[s.shift()];
return obj;
}

alert(deeptest('t.level1.level2.level3') || 'Undefined');


It returns undefined if any of the segments is undefined.






share|improve this answer



















  • 3




    Worth noting that this method is very performant, at least in Chrome, in some cases outperforming @Claudiu modified version of selected answer. See performance test here: jsperf.com/check-if-deep-property-exists-with-willnotthrow
    – netpoetica
    Nov 27 '14 at 5:32


















up vote
23
down vote













var a;

a = {
b: {
c: 'd'
}
};

function isset (fn) {
var value;
try {
value = fn();
} catch (e) {
value = undefined;
} finally {
return value !== undefined;
}
};

// ES5
console.log(
isset(function () { return a.b.c; }),
isset(function () { return a.b.c.d.e.f; })
);


If you are coding in ES6 environment (or using 6to5) then you can take advantage of the arrow function syntax:



// ES6 using the arrow function
console.log(
isset(() => a.b.c),
isset(() => a.b.c.d.e.f)
);


Regarding the performance, there is no performance penalty for using try..catch block if the property is set. There is a performance impact if the property is unset.



Consider simply using _.has:



var object = { 'a': { 'b': { 'c': 3 } } };

_.has(object, 'a');
// → true

_.has(object, 'a.b.c');
// → true

_.has(object, ['a', 'b', 'c']);
// → true





share|improve this answer



















  • 2




    I think the try-catch approach is the best answer. There's a philosophical difference between querying an object for its type, and assuming the API exists and failing accordingly if it doesn't. The latter is more appropriate in loosely typed languages. See stackoverflow.com/a/408305/2419669. The try-catch approach is also far clearer than if (foo && foo.bar && foo.bar.baz && foo.bar.baz.qux) { ... }.
    – yangmillstheory
    Jan 31 '16 at 3:39












  • Out of all the answers on StackOverflow, this answer actually worked. And i tried them all for various nested object properties and key values existence checks. Thanks!
    – Jonathan Marzullo
    Jul 19 '16 at 15:30


















up vote
17
down vote













how about



try {
alert(test.level1.level2.level3)
} catch(e) {
...whatever

}





share|improve this answer

















  • 13




    I don't think try/catch is a good way to test for existence of an object: try/catch is meant to handle exceptions, not normal conditions such as the test here. I think (typeof foo == "undefined") at each step is better -- and in general, there's probably some refactoring required if you're working with such deeply nested properties. Also, try/catch will cause a break in Firebug (and in any browser where break-on-error is turned on) if an exception is thrown.
    – Sam Dutton
    Nov 9 '10 at 12:00










  • I vote on this, because browser will check the existence twice if you use other solutions. Lets say you want to call ´a.c.b = 2´. Browser has to check the existence before modifying the value (otherwise it would be a memory error caught by OS).
    – user669677
    Sep 2 '13 at 12:04






  • 4




    The question still remain: witch one is faster for browsers to set up a try catch or call hasOwnProperty() n times?
    – user669677
    Sep 2 '13 at 12:12








  • 12




    Why is this bad again? This looks cleanest to me.
    – Austin Pray
    Jun 4 '14 at 19:26










  • I would say: If you expect that the property exist than it is okay to wrap it into a try block. If it then doesn't exist it is an error. But if you're just lazy and put regular code into the catch block for the case that the property doesn't exist try/catch is misused. Here a if/else or something similar is required.
    – robsch
    Aug 9 '16 at 13:55


















up vote
9
down vote













ES6 answer, thoroughly tested :)



const propExists = (obj, path) => {
return !!path.split('.').reduce((obj, prop) => {
return obj && obj[prop] ? obj[prop] : undefined;
}, obj)
}


→see Codepen with full test coverage






share|improve this answer





















  • I made your tests failed setting the value of the flat prop to 0. You must care about type coercion.
    – germain
    Oct 2 at 7:13










  • @germain Does this work for you? (I explicitly compare === for the different falsys, and added test. If you have a better idea, let me know).
    – Frank Nocke
    Oct 2 at 11:22










  • I made your tests failed again setting the value of the flat prop to false. And then you might want to have a value in your object set to undefined (I know it's weird but is is JS). I made a positive false value set to 'Prop not Found': const hasTruthyProp = prop => prop === 'Prop not found' ? false : true const path = obj => path => path.reduce((obj, prop) => { return obj && obj.hasOwnProperty(prop) ? obj[prop] : 'Prop not found' }, obj) const myFunc = compose(hasTruthyProp, path(obj))
    – germain
    Oct 2 at 15:19












  • Can you fork my codepen (top-right, easy), correct & add tests, and send me the URL of yours? Thanks =)
    – Frank Nocke
    Oct 3 at 18:16










  • Check this
    – germain
    Oct 4 at 5:01


















up vote
8
down vote













I tried a recursive approach:



function objHasKeys(obj, keys) {
var next = keys.shift();
return obj[next] && (! keys.length || objHasKeys(obj[next], keys));
}


The ! keys.length || kicks out of the recursion so it doesn't run the function with no keys left to test. Tests:



obj = {
path: {
to: {
the: {
goodKey: "hello"
}
}
}
}

console.log(objHasKeys(obj, ['path', 'to', 'the', 'goodKey'])); // true
console.log(objHasKeys(obj, ['path', 'to', 'the', 'badKey'])); // undefined


I am using it to print a friendly html view of a bunch of objects with unknown key/values, e.g.:



var biosName = objHasKeys(myObj, 'MachineInfo:BiosInfo:Name'.split(':'))
? myObj.MachineInfo.BiosInfo.Name
: 'unknown';





share|improve this answer




























    up vote
    6
    down vote













    You can also use tc39 optional chaining proposal together with babel 7 - tc39-proposal-optional-chaining



    Code would look like this:



      const test = test?.level1?.level2?.level3;
    if (test) alert(test);





    share|improve this answer





















    • Note that this syntax will almost certainly change, as some TC39 members have objections.
      – jhpratt
      Sep 24 at 1:59










    • Probably but this will be available in some form in time, and that's the only thing that matters .. It's one of the features I miss the most in JS.
      – Goran.it
      Sep 24 at 7:00


















    up vote
    5
    down vote













    I think the following script gives more readable representation.



    declare a function:



    var o = function(obj) { return obj || {};};


    then use it like this:



    if (o(o(o(o(test).level1).level2).level3)
    {

    }


    I call it "sad clown technique" because it is using sign o(





    EDIT:



    here is a version for TypeScript



    it gives type checks at compile time (as well as the intellisense if you use a tool like Visual Studio)



    export function o<T>(someObject: T, defaultValue: T = {} as T) : T {
    if (typeof someObject === 'undefined' || someObject === null)
    return defaultValue;
    else
    return someObject;
    }


    the usage is the same:



    o(o(o(o(test).level1).level2).level3


    but this time intellisense works!



    plus, you can set a default value:



    o(o(o(o(o(test).level1).level2).level3, "none")





    share|improve this answer























    • °0o <°(())))><
      – DanFromGermany
      Nov 17 '16 at 14:23


















    up vote
    5
    down vote













    I didn't see any example of someone using Proxies



    So I came up with my own.
    The great thing about it is that you don't have to interpolate strings. You can actually return a chain-able object function and do some magical things with it. You can even call functions and get array indexes to check for deep objects






    function resolve(target) {
    var noop = () => {} // We us a noop function so we can call methods also
    return new Proxy(noop, {
    get(noop, key) {
    // return end result if key is _result
    return key === '_result'
    ? target
    : resolve( // resolve with target value or undefined
    target === undefined ? undefined : target[key]
    )
    },

    // if we want to test a function then we can do so alos thanks to using noop
    // instead of using target in our proxy
    apply(noop, that, args) {
    return resolve(typeof target === 'function' ? target.apply(that, args) : undefined)
    },
    })
    }

    // some modified examples from the accepted answer
    var test = {level1: {level2:() => ({level3:'level3'})}}
    var test1 = {key1: {key2: ['item0']}}

    // You need to get _result in the end to get the final result

    console.log(resolve(test).level1.level2().level3._result)
    console.log(resolve(test).level1.level2().level3.level4.level5._result)
    console.log(resolve(test1).key1.key2[0]._result)
    console.log(resolve(test1)[0].key._result) // don't exist





    The above code works fine for synchronous stuff. But how would you test something that is asynchronous like this ajax call?
    How do you test that? what if the response isn't json when it returns a 500 http error?



    window.fetch('https://httpbin.org/get')
    .then(function(response) {
    return response.json()
    })
    .then(function(json) {
    console.log(json.headers['User-Agent'])
    })


    sure you could use async/await to get rid of some callbacks. But what if you could do it even more magically? something that looks like this:



    fetch('https://httpbin.org/get').json().headers['User-Agent']


    You probably wonder where all the promise & .then chains are... this could be blocking for all that you know... but using the same Proxy technique with promise you can actually test deeply nested complex path for it existence without ever writing a single function






    function resolve(target) { 
    return new Proxy(() => {}, {
    get(noop, key) {
    return key === 'then' ? target.then.bind(target) : resolve(
    Promise.resolve(target).then(target => {
    if (typeof target[key] === 'function') return target[key].bind(target)
    return target[key]
    })
    )
    },

    apply(noop, that, args) {
    return resolve(target.then(result => {
    return result.apply(that, args)
    }))
    },
    })
    }

    // this feels very much synchronous but are still non blocking :)
    resolve(window) // this will chain a noop function until you call then()
    .fetch('https://httpbin.org/get')
    .json()
    .headers['User-Agent']
    .then(console.log, console.warn) // you get a warning if it doesn't exist

    // You could use this method also for the first test object
    // also, but it would have to call .then() in the end



    // Another example
    resolve(window)
    .fetch('https://httpbin.org/get?items=4&items=2')
    .json()
    .args
    .items
    // nice that you can map an array item without even having it ready
    .map(n => ~~n * 4)
    .then(console.log, console.warn) // you get a warning if it doesn't exist








    share|improve this answer























    • If someone is interested, I've publish the async version on npm
      – Endless
      Sep 4 '17 at 12:09




















    up vote
    4
    down vote













    One simple way is this:



    try {
    alert(test.level1.level2.level3);
    } catch(e) {
    alert("undefined"); // this is optional to put any output here
    }


    The try/catch catches the cases for when any of the higher level objects such as test, test.level1, test.level1.level2 are not defined.






    share|improve this answer




























      up vote
      3
      down vote













      A shorter, ES5 version of @CMS's excellent answer:



      // Check the obj has the keys in the order mentioned. Used for checking JSON results.  
      var checkObjHasKeys = function(obj, keys) {
      var success = true;
      keys.forEach( function(key) {
      if ( ! obj.hasOwnProperty(key)) {
      success = false;
      }
      obj = obj[key];
      })
      return success;
      }


      With a similar test:



      var test = { level1:{level2:{level3:'result'}}};
      utils.checkObjHasKeys(test, ['level1', 'level2', 'level3']); // true
      utils.checkObjHasKeys(test, ['level1', 'level2', 'foo']); // false





      share|improve this answer





















      • the only issue with this is if there are multiple levels of undefined keys, then you get a TypeError, e.g. checkObjHasKeys(test, ['level1', 'level2', 'asdf', 'asdf']);
        – JKS
        Jul 19 '12 at 17:34






      • 1




        A more suitable method is every, whose value can be returned directly.
        – RobG
        Aug 12 '15 at 11:59










      • Maybe change success = false; to return false. You should bail out once you know it breaks, nothing deeper can exist once it's null or undefined. This would prevent the errors on the deeper nested items, since they obviously don't exist either.
        – Wade
        Nov 4 '16 at 20:16


















      up vote
      3
      down vote













      Based on this answer, I came up with this generic function using ES2015 which would solve the problem



      function validChain( object, ...keys ) {
      return keys.reduce( ( a, b ) => ( a || { } )[ b ], object ) !== undefined;
      }

      var test = {
      first: {
      second: {
      third: "This is not the key your are looking for"
      }
      }
      }

      if ( validChain( test, "first", "second", "third" ) ) {
      console.log( test.first.second.third );
      }





      share|improve this answer



















      • 1




        Here is my final approach function validChain (object, path) { return path.split('.').reduce((a, b) => (a || { })[b], object) !== undefined }
        – James Harrington
        Nov 10 '17 at 21:45


















      up vote
      2
      down vote













      The answer given by CMS works fine with the following modification for null checks as well



      function checkNested(obj /*, level1, level2, ... levelN*/) 
      {
      var args = Array.prototype.slice.call(arguments),
      obj = args.shift();

      for (var i = 0; i < args.length; i++)
      {
      if (obj == null || !obj.hasOwnProperty(args[i]) )
      {
      return false;
      }
      obj = obj[args[i]];
      }
      return true;
      }





      share|improve this answer




























        up vote
        2
        down vote













        Following options were elaborated starting from this answer. Same tree for both :



        var o = { a: { b: { c: 1 } } };




        Stop searching when undefined



        var u = undefined;
        o.a ? o.a.b ? o.a.b.c : u : u // 1
        o.x ? o.x.y ? o.x.y.z : u : u // undefined
        (o = o.a) ? (o = o.b) ? o.c : u : u // 1




        Ensure each level one by one



        var $ = function (empty) {
        return function (node) {
        return node || empty;
        };
        }({});

        $($(o.a).b).c // 1
        $($(o.x).y).z // undefined





        share|improve this answer






























          up vote
          2
          down vote













          I know this question is old, but I wanted to offer an extension by adding this to all objects. I know people tend to frown on using the Object prototype for extended object functionality, but I don't find anything easier than doing this. Plus, it's now allowed for with the Object.defineProperty method.



          Object.defineProperty( Object.prototype, "has", { value: function( needle ) {
          var obj = this;
          var needles = needle.split( "." );
          for( var i = 0; i<needles.length; i++ ) {
          if( !obj.hasOwnProperty(needles[i])) {
          return false;
          }
          obj = obj[needles[i]];
          }
          return true;
          }});


          Now, in order to test for any property in any object you can simply do:



          if( obj.has("some.deep.nested.object.somewhere") )


          Here's a jsfiddle to test it out, and in particular it includes some jQuery that breaks if you modify the Object.prototype directly because of the property becoming enumerable. This should work fine with 3rd party libraries.






          share|improve this answer





















          • This won't work with array access ([0])
            – Royi Namir
            Oct 2 '15 at 15:15


















          up vote
          2
          down vote













          I think this is a slight improvement (becomes a 1-liner):



             alert( test.level1 && test.level1.level2 && test.level1.level2.level3 )


          This works because the && operator returns the final operand it evaluated (and it short-circuits).






          share|improve this answer




























            up vote
            2
            down vote













            This works with all objects and arrays :)



            ex:



            if( obj._has( "something.['deep']['under'][1][0].item" ) ) {
            //do something
            }


            this is my improved version of Brian's answer



            I used _has as the property name because it can conflict with existing has property (ex: maps)



            Object.defineProperty( Object.prototype, "_has", { value: function( needle ) {
            var obj = this;
            var needles = needle.split( "." );
            var needles_full=;
            var needles_square;
            for( var i = 0; i<needles.length; i++ ) {
            needles_square = needles[i].split( "[" );
            if(needles_square.length>1){
            for( var j = 0; j<needles_square.length; j++ ) {
            if(needles_square[j].length){
            needles_full.push(needles_square[j]);
            }
            }
            }else{
            needles_full.push(needles[i]);
            }
            }
            for( var i = 0; i<needles_full.length; i++ ) {
            var res = needles_full[i].match(/^((d+)|"(.+)"|'(.+)')]$/);
            if (res != null) {
            for (var j = 0; j < res.length; j++) {
            if (res[j] != undefined) {
            needles_full[i] = res[j];
            }
            }
            }

            if( typeof obj[needles_full[i]]=='undefined') {
            return false;
            }
            obj = obj[needles_full[i]];
            }
            return true;
            }});


            Here's the fiddle






            share|improve this answer






























              up vote
              2
              down vote













              Here's my take on it - most of these solutions ignore the case of a nested array as in:



                  obj = {
              "l1":"something",
              "l2":[{k:0},{k:1}],
              "l3":{
              "subL":"hello"
              }
              }


              I may want to check for obj.l2[0].k



              With the function below, you can do deeptest('l2[0].k',obj)



              The function will return true if the object exists, false otherwise






              function deeptest(keyPath, testObj) {
              var obj;

              keyPath = keyPath.split('.')
              var cKey = keyPath.shift();

              function get(pObj, pKey) {
              var bracketStart, bracketEnd, o;

              bracketStart = pKey.indexOf("[");
              if (bracketStart > -1) { //check for nested arrays
              bracketEnd = pKey.indexOf("]");
              var arrIndex = pKey.substr(bracketStart + 1, bracketEnd - bracketStart - 1);
              pKey = pKey.substr(0, bracketStart);
              var n = pObj[pKey];
              o = n? n[arrIndex] : undefined;

              } else {
              o = pObj[pKey];
              }
              return o;
              }

              obj = get(testObj, cKey);
              while (obj && keyPath.length) {
              obj = get(obj, keyPath.shift());
              }
              return typeof(obj) !== 'undefined';
              }

              var obj = {
              "l1":"level1",
              "arr1":[
              {"k":0},
              {"k":1},
              {"k":2}
              ],
              "sub": {
              "a":"letter A",
              "b":"letter B"
              }
              };
              console.log("l1: " + deeptest("l1",obj));
              console.log("arr1[0]: " + deeptest("arr1[0]",obj));
              console.log("arr1[1].k: " + deeptest("arr1[1].k",obj));
              console.log("arr1[1].j: " + deeptest("arr1[1].j",obj));
              console.log("arr1[3]: " + deeptest("arr1[3]",obj));
              console.log("arr2: " + deeptest("arr2",obj));








              share|improve this answer






























                up vote
                2
                down vote













                Now we can also use reduce to loop through nested keys:






                // @params o<object>
                // @params path<string> expects 'obj.prop1.prop2.prop3'
                // returns: obj[path] value or 'false' if prop doesn't exist

                const objPropIfExists = o => path => {
                const levels = path.split('.');
                const res = (levels.length > 0)
                ? levels.reduce((a, c) => a[c] || 0, o)
                : o[path];
                return (!!res) ? res : false
                }

                const obj = {
                name: 'Name',
                sys: { country: 'AU' },
                main: { temp: '34', temp_min: '13' },
                visibility: '35%'
                }

                const exists = objPropIfExists(obj)('main.temp')
                const doesntExist = objPropIfExists(obj)('main.temp.foo.bar.baz')

                console.log(exists, doesntExist)








                share|improve this answer




























                  up vote
                  2
                  down vote













                  I thought I'd add another one that I came up with today. The reason I am proud of this solution is that it avoids nested brackets that are used in many solutions such as Object Wrap (by Oliver Steele):



                  (in this example I use an underscore as a placeholder variable, but any variable name will work)






                  //the 'test' object
                  var test = {level1: {level2: {level3: 'level3'}}};

                  let _ = test;

                  if ((_=_.level1) && (_=_.level2) && (_=_.level3)) {

                  let level3 = _;
                  //do stuff with level3

                  }








                  //you could also use 'stacked' if statements. This helps if your object goes very deep. 
                  //(formatted without nesting or curly braces except the last one)

                  let _ = test;

                  if (_=_.level1)
                  if (_=_.level2)
                  if (_=_.level3) {

                  let level3 = _;
                  //do stuff with level3
                  }


                  //or you can indent:
                  if (_=_.level1)
                  if (_=_.level2)
                  if (_=_.level3) {

                  let level3 = _;
                  //do stuff with level3
                  }








                  share|improve this answer






























                    up vote
                    1
                    down vote













                    theres a function here on thecodeabode (safeRead) which will do this in a safe manner... i.e.



                    safeRead(test, 'level1', 'level2', 'level3');


                    if any property is null or undefined, an empty string is returned






                    share|improve this answer





















                    • I kind of like this method with templating because it returns an empty string if not set
                      – Lounge9
                      Jan 21 '16 at 19:26


















                    up vote
                    1
                    down vote













                    Based on a previous comment, here is another version where the main object could not be defined either:



                    // Supposing that our property is at first.second.third.property:
                    var property = (((typeof first !== 'undefined' ? first : {}).second || {}).third || {}).property;





                    share|improve this answer






























                      up vote
                      1
                      down vote













                      I wrote my own function that takes the desired path, and has a good and bad callback function.



                      function checkForPathInObject(object, path, callbackGood, callbackBad){
                      var pathParts = path.split(".");
                      var currentObjectPath = object;

                      // Test every step to see if it exists in object
                      for(var i=0; i<(pathParts.length); i++){
                      var currentPathPart = pathParts[i];
                      if(!currentObjectPath.hasOwnProperty(pathParts[i])){
                      if(callbackBad){
                      callbackBad();
                      }
                      return false;
                      } else {
                      currentObjectPath = currentObjectPath[pathParts[i]];
                      }
                      }

                      // call full path in callback
                      callbackGood();
                      }


                      Usage:



                      var testObject = {
                      level1:{
                      level2:{
                      level3:{
                      }
                      }
                      }
                      };


                      checkForPathInObject(testObject, "level1.level2.level3", function(){alert("good!")}, function(){alert("bad!")}); // good

                      checkForPathInObject(testObject, "level1.level2.level3.levelNotThere", function(){alert("good!")}, function(){alert("bad!")}); //bad





                      share|improve this answer





















                      • I though fair to give you credit for the inspiration to adapt your code to my answer
                        – davewoodhall
                        Jun 2 '16 at 20:02




















                      up vote
                      1
                      down vote













                      //Just in case is not supported or not included by your framework
                      //***************************************************
                      Array.prototype.some = function(fn, thisObj) {
                      var scope = thisObj || window;
                      for ( var i=0, j=this.length; i < j; ++i ) {
                      if ( fn.call(scope, this[i], i, this) ) {
                      return true;
                      }
                      }
                      return false;
                      };
                      //****************************************************

                      function isSet (object, string) {
                      if (!object) return false;
                      var childs = string.split('.');
                      if (childs.length > 0 ) {
                      return !childs.some(function (item) {
                      if (item in object) {
                      object = object[item];
                      return false;
                      } else return true;
                      });
                      } else if (string in object) {
                      return true;
                      } else return false;
                      }

                      var object = {
                      data: {
                      item: {
                      sub_item: {
                      bla: {
                      here : {
                      iam: true
                      }
                      }
                      }
                      }
                      }
                      };

                      console.log(isSet(object,'data.item')); // true
                      console.log(isSet(object,'x')); // false
                      console.log(isSet(object,'data.sub_item')); // false
                      console.log(isSet(object,'data.item')); // true
                      console.log(isSet(object,'data.item.sub_item.bla.here.iam')); // true





                      share|improve this answer




























                        up vote
                        1
                        down vote













                        I was looking for the value to be returned if the property exists, so I modified the answer by CMS above. Here's what I came up with:






                        function getNestedProperty(obj, key) {
                        // Get property array from key string
                        var properties = key.split(".");

                        // Iterate through properties, returning undefined if object is null or property doesn't exist
                        for (var i = 0; i < properties.length; i++) {
                        if (!obj || !obj.hasOwnProperty(properties[i])) {
                        return;
                        }
                        obj = obj[properties[i]];
                        }

                        // Nested property found, so return the value
                        return obj;
                        }


                        Usage:

                        getNestedProperty(test, "level1.level2.level3") // "level3"
                        getNestedProperty(test, "level1.level2.foo") // undefined








                        share|improve this answer




























                          up vote
                          1
                          down vote













                          I was having the same issue and and wanted to see if I could come up with a my own solution. This accepts the path you want to check as a string.



                          function checkPathForTruthy(obj, path) {
                          if (/[[a-zA-Z_]/.test(path)) {
                          console.log("Cannot resolve variables in property accessors");
                          return false;
                          }

                          path = path.replace(/[/g, ".");
                          path = path.replace(/]|'|"/g, "");
                          path = path.split(".");

                          var steps = 0;
                          var lastRef = obj;
                          var exists = path.every(key => {
                          var currentItem = lastRef[path[steps]];
                          if (currentItem) {
                          lastRef = currentItem;
                          steps++;
                          return true;
                          } else {
                          return false;
                          }
                          });

                          return exists;
                          }


                          Here is a snippet with some logging and test cases:






                          console.clear();
                          var testCases = [
                          ["data.Messages[0].Code", true],
                          ["data.Messages[1].Code", true],
                          ["data.Messages[0]['Code']", true],
                          ['data.Messages[0]["Code"]', true],
                          ["data[Messages][0]['Code']", false],
                          ["data['Messages'][0]['Code']", true]
                          ];
                          var path = "data.Messages[0].Code";
                          var obj = {
                          data: {
                          Messages: [{
                          Code: "0"
                          }, {
                          Code: "1"
                          }]
                          }
                          }

                          function checkPathForTruthy(obj, path) {
                          if (/[[a-zA-Z_]/.test(path)) {
                          console.log("Cannot resolve variables in property accessors");
                          return false;
                          }

                          path = path.replace(/[/g, ".");
                          path = path.replace(/]|'|"/g, "");
                          path = path.split(".");

                          var steps = 0;
                          var lastRef = obj;
                          var logOutput = ;
                          var exists = path.every(key => {
                          var currentItem = lastRef[path[steps]];
                          if (currentItem) {
                          logOutput.push(currentItem);
                          lastRef = currentItem;
                          steps++;
                          return true;
                          } else {
                          return false;
                          }
                          });
                          console.log(exists, logOutput);
                          return exists;
                          }

                          testCases.forEach(testCase => {
                          if (checkPathForTruthy(obj, testCase[0]) === testCase[1]) {
                          console.log("Passed: " + testCase[0]);
                          } else {
                          console.log("Failed: " + testCase[0] + " expected " + testCase[1]);
                          }
                          });








                          share|improve this answer






























                            up vote
                            1
                            down vote













                            Slight edit to this answer to allow nested arrays in the path






                            var has = function (obj, key) {
                            return key.split(".").every(function (x) {
                            if (typeof obj != "object" || obj === null || !x in obj)
                            return false;
                            if (obj.constructor === Array)
                            obj = obj[0];
                            obj = obj[x];
                            return true;
                            });
                            }





                            Check linked answer for usages :)






                            share|improve this answer

























                              1 2
                              next



                              Your Answer






                              StackExchange.ifUsing("editor", function () {
                              StackExchange.using("externalEditor", function () {
                              StackExchange.using("snippets", function () {
                              StackExchange.snippets.init();
                              });
                              });
                              }, "code-snippets");

                              StackExchange.ready(function() {
                              var channelOptions = {
                              tags: "".split(" "),
                              id: "1"
                              };
                              initTagRenderer("".split(" "), "".split(" "), channelOptions);

                              StackExchange.using("externalEditor", function() {
                              // Have to fire editor after snippets, if snippets enabled
                              if (StackExchange.settings.snippets.snippetsEnabled) {
                              StackExchange.using("snippets", function() {
                              createEditor();
                              });
                              }
                              else {
                              createEditor();
                              }
                              });

                              function createEditor() {
                              StackExchange.prepareEditor({
                              heartbeatType: 'answer',
                              convertImagesToLinks: true,
                              noModals: true,
                              showLowRepImageUploadWarning: true,
                              reputationToPostImages: 10,
                              bindNavPrevention: true,
                              postfix: "",
                              imageUploader: {
                              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
                              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
                              allowUrls: true
                              },
                              onDemand: false,
                              discardSelector: ".discard-answer"
                              ,immediatelyShowMarkdownHelp:true
                              });


                              }
                              });














                              draft saved

                              draft discarded


















                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f2631001%2ftest-for-existence-of-nested-javascript-object-key%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown




















                              StackExchange.ready(function () {
                              $("#show-editor-button input, #show-editor-button button").click(function () {
                              var showEditor = function() {
                              $("#show-editor-button").hide();
                              $("#post-form").removeClass("dno");
                              StackExchange.editor.finallyInit();
                              };

                              var useFancy = $(this).data('confirm-use-fancy');
                              if(useFancy == 'True') {
                              var popupTitle = $(this).data('confirm-fancy-title');
                              var popupBody = $(this).data('confirm-fancy-body');
                              var popupAccept = $(this).data('confirm-fancy-accept-button');

                              $(this).loadPopup({
                              url: '/post/self-answer-popup',
                              loaded: function(popup) {
                              var pTitle = $(popup).find('h2');
                              var pBody = $(popup).find('.popup-body');
                              var pSubmit = $(popup).find('.popup-submit');

                              pTitle.text(popupTitle);
                              pBody.html(popupBody);
                              pSubmit.val(popupAccept).click(showEditor);
                              }
                              })
                              } else{
                              var confirmText = $(this).data('confirm-text');
                              if (confirmText ? confirm(confirmText) : true) {
                              showEditor();
                              }
                              }
                              });
                              });






                              48 Answers
                              48






                              active

                              oldest

                              votes








                              48 Answers
                              48






                              active

                              oldest

                              votes









                              active

                              oldest

                              votes






                              active

                              oldest

                              votes








                              1 2
                              next









                              up vote
                              313
                              down vote



                              accepted
                              +500










                              You have to do it step by step if you don't want a TypeError, because if one of the members is null or undefined, and you try to access a member an exception will be thrown.



                              You can either simply catch the exception, or make a function to test the existence of multiple levels, something like this:



                              function checkNested(obj /*, level1, level2, ... levelN*/) {
                              var args = Array.prototype.slice.call(arguments, 1);

                              for (var i = 0; i < args.length; i++) {
                              if (!obj || !obj.hasOwnProperty(args[i])) {
                              return false;
                              }
                              obj = obj[args[i]];
                              }
                              return true;
                              }

                              var test = {level1:{level2:{level3:'level3'}} };

                              checkNested(test, 'level1', 'level2', 'level3'); // true
                              checkNested(test, 'level1', 'level2', 'foo'); // false





                              share|improve this answer



















                              • 4




                                arguments is not actually an array. Array.prototype.slice.call(arguments) converts it to a formal array. Learn
                                – deefour
                                Nov 10 '12 at 1:00








                              • 22




                                this'd be a lot more efficient to do var obj = arguments[0]; and start from var i = 1 instead of copying the arguments object
                                – Claudiu
                                Oct 31 '13 at 19:45








                              • 17




                                FYI, you can also use _.get() from lodash for this lodash.com/docs#get
                                – vasa
                                Oct 12 '15 at 21:19






                              • 3




                                In ES6 the args variable declaration can be removed and and ...args can be used as the second argument for the checkNested method. developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
                                – Vernon
                                Dec 28 '16 at 15:49






                              • 2




                                This is a very unmaintainable. If any property keys change (they will), all devs on the project would have to 'string search' the entire codebase. This isn't really a solution to the problem, as it introduces a much bigger problem
                                – Drenai
                                Jan 14 at 11:20

















                              up vote
                              313
                              down vote



                              accepted
                              +500










                              You have to do it step by step if you don't want a TypeError, because if one of the members is null or undefined, and you try to access a member an exception will be thrown.



                              You can either simply catch the exception, or make a function to test the existence of multiple levels, something like this:



                              function checkNested(obj /*, level1, level2, ... levelN*/) {
                              var args = Array.prototype.slice.call(arguments, 1);

                              for (var i = 0; i < args.length; i++) {
                              if (!obj || !obj.hasOwnProperty(args[i])) {
                              return false;
                              }
                              obj = obj[args[i]];
                              }
                              return true;
                              }

                              var test = {level1:{level2:{level3:'level3'}} };

                              checkNested(test, 'level1', 'level2', 'level3'); // true
                              checkNested(test, 'level1', 'level2', 'foo'); // false





                              share|improve this answer



















                              • 4




                                arguments is not actually an array. Array.prototype.slice.call(arguments) converts it to a formal array. Learn
                                – deefour
                                Nov 10 '12 at 1:00








                              • 22




                                this'd be a lot more efficient to do var obj = arguments[0]; and start from var i = 1 instead of copying the arguments object
                                – Claudiu
                                Oct 31 '13 at 19:45








                              • 17




                                FYI, you can also use _.get() from lodash for this lodash.com/docs#get
                                – vasa
                                Oct 12 '15 at 21:19






                              • 3




                                In ES6 the args variable declaration can be removed and and ...args can be used as the second argument for the checkNested method. developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
                                – Vernon
                                Dec 28 '16 at 15:49






                              • 2




                                This is a very unmaintainable. If any property keys change (they will), all devs on the project would have to 'string search' the entire codebase. This isn't really a solution to the problem, as it introduces a much bigger problem
                                – Drenai
                                Jan 14 at 11:20















                              up vote
                              313
                              down vote



                              accepted
                              +500







                              up vote
                              313
                              down vote



                              accepted
                              +500




                              +500




                              You have to do it step by step if you don't want a TypeError, because if one of the members is null or undefined, and you try to access a member an exception will be thrown.



                              You can either simply catch the exception, or make a function to test the existence of multiple levels, something like this:



                              function checkNested(obj /*, level1, level2, ... levelN*/) {
                              var args = Array.prototype.slice.call(arguments, 1);

                              for (var i = 0; i < args.length; i++) {
                              if (!obj || !obj.hasOwnProperty(args[i])) {
                              return false;
                              }
                              obj = obj[args[i]];
                              }
                              return true;
                              }

                              var test = {level1:{level2:{level3:'level3'}} };

                              checkNested(test, 'level1', 'level2', 'level3'); // true
                              checkNested(test, 'level1', 'level2', 'foo'); // false





                              share|improve this answer














                              You have to do it step by step if you don't want a TypeError, because if one of the members is null or undefined, and you try to access a member an exception will be thrown.



                              You can either simply catch the exception, or make a function to test the existence of multiple levels, something like this:



                              function checkNested(obj /*, level1, level2, ... levelN*/) {
                              var args = Array.prototype.slice.call(arguments, 1);

                              for (var i = 0; i < args.length; i++) {
                              if (!obj || !obj.hasOwnProperty(args[i])) {
                              return false;
                              }
                              obj = obj[args[i]];
                              }
                              return true;
                              }

                              var test = {level1:{level2:{level3:'level3'}} };

                              checkNested(test, 'level1', 'level2', 'level3'); // true
                              checkNested(test, 'level1', 'level2', 'foo'); // false






                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              edited Jan 25 '15 at 15:45









                              Esailija

                              118k14211285




                              118k14211285










                              answered Apr 13 '10 at 16:12









                              CMS

                              585k162839809




                              585k162839809








                              • 4




                                arguments is not actually an array. Array.prototype.slice.call(arguments) converts it to a formal array. Learn
                                – deefour
                                Nov 10 '12 at 1:00








                              • 22




                                this'd be a lot more efficient to do var obj = arguments[0]; and start from var i = 1 instead of copying the arguments object
                                – Claudiu
                                Oct 31 '13 at 19:45








                              • 17




                                FYI, you can also use _.get() from lodash for this lodash.com/docs#get
                                – vasa
                                Oct 12 '15 at 21:19






                              • 3




                                In ES6 the args variable declaration can be removed and and ...args can be used as the second argument for the checkNested method. developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
                                – Vernon
                                Dec 28 '16 at 15:49






                              • 2




                                This is a very unmaintainable. If any property keys change (they will), all devs on the project would have to 'string search' the entire codebase. This isn't really a solution to the problem, as it introduces a much bigger problem
                                – Drenai
                                Jan 14 at 11:20
















                              • 4




                                arguments is not actually an array. Array.prototype.slice.call(arguments) converts it to a formal array. Learn
                                – deefour
                                Nov 10 '12 at 1:00








                              • 22




                                this'd be a lot more efficient to do var obj = arguments[0]; and start from var i = 1 instead of copying the arguments object
                                – Claudiu
                                Oct 31 '13 at 19:45








                              • 17




                                FYI, you can also use _.get() from lodash for this lodash.com/docs#get
                                – vasa
                                Oct 12 '15 at 21:19






                              • 3




                                In ES6 the args variable declaration can be removed and and ...args can be used as the second argument for the checkNested method. developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
                                – Vernon
                                Dec 28 '16 at 15:49






                              • 2




                                This is a very unmaintainable. If any property keys change (they will), all devs on the project would have to 'string search' the entire codebase. This isn't really a solution to the problem, as it introduces a much bigger problem
                                – Drenai
                                Jan 14 at 11:20










                              4




                              4




                              arguments is not actually an array. Array.prototype.slice.call(arguments) converts it to a formal array. Learn
                              – deefour
                              Nov 10 '12 at 1:00






                              arguments is not actually an array. Array.prototype.slice.call(arguments) converts it to a formal array. Learn
                              – deefour
                              Nov 10 '12 at 1:00






                              22




                              22




                              this'd be a lot more efficient to do var obj = arguments[0]; and start from var i = 1 instead of copying the arguments object
                              – Claudiu
                              Oct 31 '13 at 19:45






                              this'd be a lot more efficient to do var obj = arguments[0]; and start from var i = 1 instead of copying the arguments object
                              – Claudiu
                              Oct 31 '13 at 19:45






                              17




                              17




                              FYI, you can also use _.get() from lodash for this lodash.com/docs#get
                              – vasa
                              Oct 12 '15 at 21:19




                              FYI, you can also use _.get() from lodash for this lodash.com/docs#get
                              – vasa
                              Oct 12 '15 at 21:19




                              3




                              3




                              In ES6 the args variable declaration can be removed and and ...args can be used as the second argument for the checkNested method. developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
                              – Vernon
                              Dec 28 '16 at 15:49




                              In ES6 the args variable declaration can be removed and and ...args can be used as the second argument for the checkNested method. developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
                              – Vernon
                              Dec 28 '16 at 15:49




                              2




                              2




                              This is a very unmaintainable. If any property keys change (they will), all devs on the project would have to 'string search' the entire codebase. This isn't really a solution to the problem, as it introduces a much bigger problem
                              – Drenai
                              Jan 14 at 11:20






                              This is a very unmaintainable. If any property keys change (they will), all devs on the project would have to 'string search' the entire codebase. This isn't really a solution to the problem, as it introduces a much bigger problem
                              – Drenai
                              Jan 14 at 11:20














                              up vote
                              306
                              down vote













                              Here is a pattern I picked up from Oliver Steele:



                              var level3 = (((test || {}).level1 || {}).level2 || {}).level3;
                              alert( level3 );


                              In fact that whole article is a discussion of how you can do this in javascript. He settles on using the above syntax (which isn't that hard to read once you get used to it) as an idiom.






                              share|improve this answer



















                              • 8




                                @wared I think it is interesting mostly for how concise it is. There is a detailed discussion of the performance characteristics in the linked post. Yes it always does all the tests, but it avoids creating temp vars, and you can alias {} to a var if you want to prevent the overhead of creating a new empty object each time. In 99% of cases I would not expect speed to matter, and in cases where it does there is no substitute for profiling.
                                – Gabe Moothart
                                Sep 5 '13 at 18:13








                              • 9




                                @MuhammadUmer No, the point of (test || {}) is that if test is undefined, then you're doing ({}.level1 || {}). Of course, {}.level1 is undefined, so that means you're doing {}.level2, and so on.
                                – Joshua Taylor
                                Apr 28 '15 at 16:06






                              • 13




                                you said "which isn't that hard to read once you get used to it". Well, these are signs you know already this is a mess. Then why suggest this solution? It is prone to typos and gives absolutely nothing to readability. Just look it! If i have to write an ugly line, it should asswell be readable; so i'm going to just stick with if(test.level1 && test.level1.level2 && test.level1.level2.level3)
                                – Sharky
                                Sep 30 '16 at 9:16








                              • 6




                                Unless I'm missing something, this won't work for boolean end-properties that might be false... sadly. Otherwise I love this idiom.
                                – T3db0t
                                Nov 17 '16 at 20:01






                              • 5




                                This is both hard to read and hard to type.
                                – pootzko
                                Jun 29 '17 at 9:36















                              up vote
                              306
                              down vote













                              Here is a pattern I picked up from Oliver Steele:



                              var level3 = (((test || {}).level1 || {}).level2 || {}).level3;
                              alert( level3 );


                              In fact that whole article is a discussion of how you can do this in javascript. He settles on using the above syntax (which isn't that hard to read once you get used to it) as an idiom.






                              share|improve this answer



















                              • 8




                                @wared I think it is interesting mostly for how concise it is. There is a detailed discussion of the performance characteristics in the linked post. Yes it always does all the tests, but it avoids creating temp vars, and you can alias {} to a var if you want to prevent the overhead of creating a new empty object each time. In 99% of cases I would not expect speed to matter, and in cases where it does there is no substitute for profiling.
                                – Gabe Moothart
                                Sep 5 '13 at 18:13








                              • 9




                                @MuhammadUmer No, the point of (test || {}) is that if test is undefined, then you're doing ({}.level1 || {}). Of course, {}.level1 is undefined, so that means you're doing {}.level2, and so on.
                                – Joshua Taylor
                                Apr 28 '15 at 16:06






                              • 13




                                you said "which isn't that hard to read once you get used to it". Well, these are signs you know already this is a mess. Then why suggest this solution? It is prone to typos and gives absolutely nothing to readability. Just look it! If i have to write an ugly line, it should asswell be readable; so i'm going to just stick with if(test.level1 && test.level1.level2 && test.level1.level2.level3)
                                – Sharky
                                Sep 30 '16 at 9:16








                              • 6




                                Unless I'm missing something, this won't work for boolean end-properties that might be false... sadly. Otherwise I love this idiom.
                                – T3db0t
                                Nov 17 '16 at 20:01






                              • 5




                                This is both hard to read and hard to type.
                                – pootzko
                                Jun 29 '17 at 9:36













                              up vote
                              306
                              down vote










                              up vote
                              306
                              down vote









                              Here is a pattern I picked up from Oliver Steele:



                              var level3 = (((test || {}).level1 || {}).level2 || {}).level3;
                              alert( level3 );


                              In fact that whole article is a discussion of how you can do this in javascript. He settles on using the above syntax (which isn't that hard to read once you get used to it) as an idiom.






                              share|improve this answer














                              Here is a pattern I picked up from Oliver Steele:



                              var level3 = (((test || {}).level1 || {}).level2 || {}).level3;
                              alert( level3 );


                              In fact that whole article is a discussion of how you can do this in javascript. He settles on using the above syntax (which isn't that hard to read once you get used to it) as an idiom.







                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              edited Jan 14 '17 at 1:02









                              Ben Creasy

                              1,58321733




                              1,58321733










                              answered Oct 27 '10 at 14:41









                              Gabe Moothart

                              22.6k126794




                              22.6k126794








                              • 8




                                @wared I think it is interesting mostly for how concise it is. There is a detailed discussion of the performance characteristics in the linked post. Yes it always does all the tests, but it avoids creating temp vars, and you can alias {} to a var if you want to prevent the overhead of creating a new empty object each time. In 99% of cases I would not expect speed to matter, and in cases where it does there is no substitute for profiling.
                                – Gabe Moothart
                                Sep 5 '13 at 18:13








                              • 9




                                @MuhammadUmer No, the point of (test || {}) is that if test is undefined, then you're doing ({}.level1 || {}). Of course, {}.level1 is undefined, so that means you're doing {}.level2, and so on.
                                – Joshua Taylor
                                Apr 28 '15 at 16:06






                              • 13




                                you said "which isn't that hard to read once you get used to it". Well, these are signs you know already this is a mess. Then why suggest this solution? It is prone to typos and gives absolutely nothing to readability. Just look it! If i have to write an ugly line, it should asswell be readable; so i'm going to just stick with if(test.level1 && test.level1.level2 && test.level1.level2.level3)
                                – Sharky
                                Sep 30 '16 at 9:16








                              • 6




                                Unless I'm missing something, this won't work for boolean end-properties that might be false... sadly. Otherwise I love this idiom.
                                – T3db0t
                                Nov 17 '16 at 20:01






                              • 5




                                This is both hard to read and hard to type.
                                – pootzko
                                Jun 29 '17 at 9:36














                              • 8




                                @wared I think it is interesting mostly for how concise it is. There is a detailed discussion of the performance characteristics in the linked post. Yes it always does all the tests, but it avoids creating temp vars, and you can alias {} to a var if you want to prevent the overhead of creating a new empty object each time. In 99% of cases I would not expect speed to matter, and in cases where it does there is no substitute for profiling.
                                – Gabe Moothart
                                Sep 5 '13 at 18:13








                              • 9




                                @MuhammadUmer No, the point of (test || {}) is that if test is undefined, then you're doing ({}.level1 || {}). Of course, {}.level1 is undefined, so that means you're doing {}.level2, and so on.
                                – Joshua Taylor
                                Apr 28 '15 at 16:06






                              • 13




                                you said "which isn't that hard to read once you get used to it". Well, these are signs you know already this is a mess. Then why suggest this solution? It is prone to typos and gives absolutely nothing to readability. Just look it! If i have to write an ugly line, it should asswell be readable; so i'm going to just stick with if(test.level1 && test.level1.level2 && test.level1.level2.level3)
                                – Sharky
                                Sep 30 '16 at 9:16








                              • 6




                                Unless I'm missing something, this won't work for boolean end-properties that might be false... sadly. Otherwise I love this idiom.
                                – T3db0t
                                Nov 17 '16 at 20:01






                              • 5




                                This is both hard to read and hard to type.
                                – pootzko
                                Jun 29 '17 at 9:36








                              8




                              8




                              @wared I think it is interesting mostly for how concise it is. There is a detailed discussion of the performance characteristics in the linked post. Yes it always does all the tests, but it avoids creating temp vars, and you can alias {} to a var if you want to prevent the overhead of creating a new empty object each time. In 99% of cases I would not expect speed to matter, and in cases where it does there is no substitute for profiling.
                              – Gabe Moothart
                              Sep 5 '13 at 18:13






                              @wared I think it is interesting mostly for how concise it is. There is a detailed discussion of the performance characteristics in the linked post. Yes it always does all the tests, but it avoids creating temp vars, and you can alias {} to a var if you want to prevent the overhead of creating a new empty object each time. In 99% of cases I would not expect speed to matter, and in cases where it does there is no substitute for profiling.
                              – Gabe Moothart
                              Sep 5 '13 at 18:13






                              9




                              9




                              @MuhammadUmer No, the point of (test || {}) is that if test is undefined, then you're doing ({}.level1 || {}). Of course, {}.level1 is undefined, so that means you're doing {}.level2, and so on.
                              – Joshua Taylor
                              Apr 28 '15 at 16:06




                              @MuhammadUmer No, the point of (test || {}) is that if test is undefined, then you're doing ({}.level1 || {}). Of course, {}.level1 is undefined, so that means you're doing {}.level2, and so on.
                              – Joshua Taylor
                              Apr 28 '15 at 16:06




                              13




                              13




                              you said "which isn't that hard to read once you get used to it". Well, these are signs you know already this is a mess. Then why suggest this solution? It is prone to typos and gives absolutely nothing to readability. Just look it! If i have to write an ugly line, it should asswell be readable; so i'm going to just stick with if(test.level1 && test.level1.level2 && test.level1.level2.level3)
                              – Sharky
                              Sep 30 '16 at 9:16






                              you said "which isn't that hard to read once you get used to it". Well, these are signs you know already this is a mess. Then why suggest this solution? It is prone to typos and gives absolutely nothing to readability. Just look it! If i have to write an ugly line, it should asswell be readable; so i'm going to just stick with if(test.level1 && test.level1.level2 && test.level1.level2.level3)
                              – Sharky
                              Sep 30 '16 at 9:16






                              6




                              6




                              Unless I'm missing something, this won't work for boolean end-properties that might be false... sadly. Otherwise I love this idiom.
                              – T3db0t
                              Nov 17 '16 at 20:01




                              Unless I'm missing something, this won't work for boolean end-properties that might be false... sadly. Otherwise I love this idiom.
                              – T3db0t
                              Nov 17 '16 at 20:01




                              5




                              5




                              This is both hard to read and hard to type.
                              – pootzko
                              Jun 29 '17 at 9:36




                              This is both hard to read and hard to type.
                              – pootzko
                              Jun 29 '17 at 9:36










                              up vote
                              207
                              down vote













                              Update



                              Looks like lodash has added _.get for all your nested property getting needs.



                              _.get(countries, 'greece.sparta.playwright')


                              https://lodash.com/docs#get





                              Previous answer



                              lodash users may enjoy lodash.contrib which has a couple methods that mitigate this problem.



                              getPath



                              Signature: _.getPath(obj:Object, ks:String|Array)



                              Gets the value at any depth in a nested object based on the path described by
                              the keys given. Keys may be given as an array or as a dot-separated string.
                              Returns undefined if the path cannot be reached.



                              var countries = {
                              greece: {
                              athens: {
                              playwright: "Sophocles"
                              }
                              }
                              }
                              };

                              _.getPath(countries, "greece.athens.playwright");
                              // => "Sophocles"

                              _.getPath(countries, "greece.sparta.playwright");
                              // => undefined

                              _.getPath(countries, ["greece", "athens", "playwright"]);
                              // => "Sophocles"

                              _.getPath(countries, ["greece", "sparta", "playwright"]);
                              // => undefined





                              share|improve this answer























                              • Lodash really needs a _.isPathDefined(obj, pathString) method.
                                – Matthew Payne
                                Jan 9 '15 at 16:34










                              • @MatthewPayne It'd be nice perhaps, but it really isn't necessary. You could do it yourself really easily function isPathDefined(object, path) { return typeof _.getPath(object, path) !== 'undefined'; }
                                – Thor84no
                                May 12 '15 at 11:33








                              • 11




                                Lodash has this same functionality itself: _.get(countries, 'greece.sparta.playwright', 'default'); // → 'default' _.has(countries, 'greece.spart.playwright') // → false
                                – Tom
                                May 15 '15 at 18:23












                              • @Tom thanks. Really glad they include that by default now.
                                – Austin Pray
                                May 15 '15 at 22:56










                              • even better would be _.result
                                – Shishir Arora
                                Aug 29 '15 at 8:50















                              up vote
                              207
                              down vote













                              Update



                              Looks like lodash has added _.get for all your nested property getting needs.



                              _.get(countries, 'greece.sparta.playwright')


                              https://lodash.com/docs#get





                              Previous answer



                              lodash users may enjoy lodash.contrib which has a couple methods that mitigate this problem.



                              getPath



                              Signature: _.getPath(obj:Object, ks:String|Array)



                              Gets the value at any depth in a nested object based on the path described by
                              the keys given. Keys may be given as an array or as a dot-separated string.
                              Returns undefined if the path cannot be reached.



                              var countries = {
                              greece: {
                              athens: {
                              playwright: "Sophocles"
                              }
                              }
                              }
                              };

                              _.getPath(countries, "greece.athens.playwright");
                              // => "Sophocles"

                              _.getPath(countries, "greece.sparta.playwright");
                              // => undefined

                              _.getPath(countries, ["greece", "athens", "playwright"]);
                              // => "Sophocles"

                              _.getPath(countries, ["greece", "sparta", "playwright"]);
                              // => undefined





                              share|improve this answer























                              • Lodash really needs a _.isPathDefined(obj, pathString) method.
                                – Matthew Payne
                                Jan 9 '15 at 16:34










                              • @MatthewPayne It'd be nice perhaps, but it really isn't necessary. You could do it yourself really easily function isPathDefined(object, path) { return typeof _.getPath(object, path) !== 'undefined'; }
                                – Thor84no
                                May 12 '15 at 11:33








                              • 11




                                Lodash has this same functionality itself: _.get(countries, 'greece.sparta.playwright', 'default'); // → 'default' _.has(countries, 'greece.spart.playwright') // → false
                                – Tom
                                May 15 '15 at 18:23












                              • @Tom thanks. Really glad they include that by default now.
                                – Austin Pray
                                May 15 '15 at 22:56










                              • even better would be _.result
                                – Shishir Arora
                                Aug 29 '15 at 8:50













                              up vote
                              207
                              down vote










                              up vote
                              207
                              down vote









                              Update



                              Looks like lodash has added _.get for all your nested property getting needs.



                              _.get(countries, 'greece.sparta.playwright')


                              https://lodash.com/docs#get





                              Previous answer



                              lodash users may enjoy lodash.contrib which has a couple methods that mitigate this problem.



                              getPath



                              Signature: _.getPath(obj:Object, ks:String|Array)



                              Gets the value at any depth in a nested object based on the path described by
                              the keys given. Keys may be given as an array or as a dot-separated string.
                              Returns undefined if the path cannot be reached.



                              var countries = {
                              greece: {
                              athens: {
                              playwright: "Sophocles"
                              }
                              }
                              }
                              };

                              _.getPath(countries, "greece.athens.playwright");
                              // => "Sophocles"

                              _.getPath(countries, "greece.sparta.playwright");
                              // => undefined

                              _.getPath(countries, ["greece", "athens", "playwright"]);
                              // => "Sophocles"

                              _.getPath(countries, ["greece", "sparta", "playwright"]);
                              // => undefined





                              share|improve this answer














                              Update



                              Looks like lodash has added _.get for all your nested property getting needs.



                              _.get(countries, 'greece.sparta.playwright')


                              https://lodash.com/docs#get





                              Previous answer



                              lodash users may enjoy lodash.contrib which has a couple methods that mitigate this problem.



                              getPath



                              Signature: _.getPath(obj:Object, ks:String|Array)



                              Gets the value at any depth in a nested object based on the path described by
                              the keys given. Keys may be given as an array or as a dot-separated string.
                              Returns undefined if the path cannot be reached.



                              var countries = {
                              greece: {
                              athens: {
                              playwright: "Sophocles"
                              }
                              }
                              }
                              };

                              _.getPath(countries, "greece.athens.playwright");
                              // => "Sophocles"

                              _.getPath(countries, "greece.sparta.playwright");
                              // => undefined

                              _.getPath(countries, ["greece", "athens", "playwright"]);
                              // => "Sophocles"

                              _.getPath(countries, ["greece", "sparta", "playwright"]);
                              // => undefined






                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              edited Apr 26 '17 at 14:32









                              mikemaccana

                              41.5k44228292




                              41.5k44228292










                              answered Jun 4 '14 at 19:53









                              Austin Pray

                              3,92421630




                              3,92421630












                              • Lodash really needs a _.isPathDefined(obj, pathString) method.
                                – Matthew Payne
                                Jan 9 '15 at 16:34










                              • @MatthewPayne It'd be nice perhaps, but it really isn't necessary. You could do it yourself really easily function isPathDefined(object, path) { return typeof _.getPath(object, path) !== 'undefined'; }
                                – Thor84no
                                May 12 '15 at 11:33








                              • 11




                                Lodash has this same functionality itself: _.get(countries, 'greece.sparta.playwright', 'default'); // → 'default' _.has(countries, 'greece.spart.playwright') // → false
                                – Tom
                                May 15 '15 at 18:23












                              • @Tom thanks. Really glad they include that by default now.
                                – Austin Pray
                                May 15 '15 at 22:56










                              • even better would be _.result
                                – Shishir Arora
                                Aug 29 '15 at 8:50


















                              • Lodash really needs a _.isPathDefined(obj, pathString) method.
                                – Matthew Payne
                                Jan 9 '15 at 16:34










                              • @MatthewPayne It'd be nice perhaps, but it really isn't necessary. You could do it yourself really easily function isPathDefined(object, path) { return typeof _.getPath(object, path) !== 'undefined'; }
                                – Thor84no
                                May 12 '15 at 11:33








                              • 11




                                Lodash has this same functionality itself: _.get(countries, 'greece.sparta.playwright', 'default'); // → 'default' _.has(countries, 'greece.spart.playwright') // → false
                                – Tom
                                May 15 '15 at 18:23












                              • @Tom thanks. Really glad they include that by default now.
                                – Austin Pray
                                May 15 '15 at 22:56










                              • even better would be _.result
                                – Shishir Arora
                                Aug 29 '15 at 8:50
















                              Lodash really needs a _.isPathDefined(obj, pathString) method.
                              – Matthew Payne
                              Jan 9 '15 at 16:34




                              Lodash really needs a _.isPathDefined(obj, pathString) method.
                              – Matthew Payne
                              Jan 9 '15 at 16:34












                              @MatthewPayne It'd be nice perhaps, but it really isn't necessary. You could do it yourself really easily function isPathDefined(object, path) { return typeof _.getPath(object, path) !== 'undefined'; }
                              – Thor84no
                              May 12 '15 at 11:33






                              @MatthewPayne It'd be nice perhaps, but it really isn't necessary. You could do it yourself really easily function isPathDefined(object, path) { return typeof _.getPath(object, path) !== 'undefined'; }
                              – Thor84no
                              May 12 '15 at 11:33






                              11




                              11




                              Lodash has this same functionality itself: _.get(countries, 'greece.sparta.playwright', 'default'); // → 'default' _.has(countries, 'greece.spart.playwright') // → false
                              – Tom
                              May 15 '15 at 18:23






                              Lodash has this same functionality itself: _.get(countries, 'greece.sparta.playwright', 'default'); // → 'default' _.has(countries, 'greece.spart.playwright') // → false
                              – Tom
                              May 15 '15 at 18:23














                              @Tom thanks. Really glad they include that by default now.
                              – Austin Pray
                              May 15 '15 at 22:56




                              @Tom thanks. Really glad they include that by default now.
                              – Austin Pray
                              May 15 '15 at 22:56












                              even better would be _.result
                              – Shishir Arora
                              Aug 29 '15 at 8:50




                              even better would be _.result
                              – Shishir Arora
                              Aug 29 '15 at 8:50










                              up vote
                              141
                              down vote













                              I have done performance tests (thank you cdMinix for adding lodash) on some of the suggestions proposed to this question with the results listed below.




                              Disclaimer #1 Turning strings into references is unnecessary meta-programming and probably best avoided. Don't lose track of your references to begin with. Read more from this answer to a similar question.



                              Disclaimer #2 We are talking about millions of operations per millisecond here. It is very unlikely any of these would make much difference in most use cases. Choose whichever makes the most sense knowing the limitations of each. For me I would go with something like reduce out of convenience.




                              Object Wrap (by Oliver Steele) – 34 % – fastest



                              var r1 = (((test || {}).level1 || {}).level2 || {}).level3;
                              var r2 = (((test || {}).level1 || {}).level2 || {}).foo;


                              Original solution (suggested in question) – 45%



                              var r1 = test.level1 && test.level1.level2 && test.level1.level2.level3;
                              var r2 = test.level1 && test.level1.level2 && test.level1.level2.foo;


                              checkNested – 50%



                              function checkNested(obj) {
                              for (var i = 1; i < arguments.length; i++) {
                              if (!obj.hasOwnProperty(arguments[i])) {
                              return false;
                              }
                              obj = obj[arguments[i]];
                              }
                              return true;
                              }


                              get_if_exist – 52%



                              function get_if_exist(str) {
                              try { return eval(str) }
                              catch(e) { return undefined }
                              }


                              validChain – 54%



                              function validChain( object, ...keys ) {
                              return keys.reduce( ( a, b ) => ( a || { } )[ b ], object ) !== undefined;
                              }


                              objHasKeys – 63%



                              function objHasKeys(obj, keys) {
                              var next = keys.shift();
                              return obj[next] && (! keys.length || objHasKeys(obj[next], keys));
                              }


                              nestedPropertyExists – 69%



                              function nestedPropertyExists(obj, props) {
                              var prop = props.shift();
                              return prop === undefined ? true : obj.hasOwnProperty(prop) ? nestedPropertyExists(obj[prop], props) : false;
                              }


                              _.get – 72%



                              deeptest – 86%



                              function deeptest(target, s){
                              s= s.split('.')
                              var obj= target[s.shift()];
                              while(obj && s.length) obj= obj[s.shift()];
                              return obj;
                              }


                              sad clowns – 100% – slowest



                              var o = function(obj) { return obj || {} };

                              var r1 = o(o(o(o(test).level1).level2).level3);
                              var r2 = o(o(o(o(test).level1).level2).foo);





                              share|improve this answer



















                              • 12




                                it should be noted that the more % a test has - the SLOWER it is
                                – avalanche1
                                Feb 3 '17 at 9:12






                              • 1




                                what about lodash _.get() ? how performant is it comparing to those answers?
                                – beniutek
                                May 31 '17 at 14:07






                              • 3




                                Tests with _.get() - jsben.ch/7aJgK
                                – cdMinix
                                Jun 27 '17 at 7:47








                              • 1




                                Each method of these is slower or faster than other ones depending on situation. If all keys are found then "Object Wrap" could be fastest, but if one of the keys is not found then "Native solution/Original solution" could be faster.
                                – evilReiko
                                Aug 28 '17 at 6:55






                              • 1




                                @evilReiko Any method will be slower if no keys are found but in proportion to each other it's still pretty much the same. However, you are right – this is more of an intellectual exercise than anything else. We are talking about a million iterations per millisecond here. I see no use case where it would make much difference. Me personally I would go for reduce or try/catch out of convenience.
                                – unitario
                                Aug 30 '17 at 6:36















                              up vote
                              141
                              down vote













                              I have done performance tests (thank you cdMinix for adding lodash) on some of the suggestions proposed to this question with the results listed below.




                              Disclaimer #1 Turning strings into references is unnecessary meta-programming and probably best avoided. Don't lose track of your references to begin with. Read more from this answer to a similar question.



                              Disclaimer #2 We are talking about millions of operations per millisecond here. It is very unlikely any of these would make much difference in most use cases. Choose whichever makes the most sense knowing the limitations of each. For me I would go with something like reduce out of convenience.




                              Object Wrap (by Oliver Steele) – 34 % – fastest



                              var r1 = (((test || {}).level1 || {}).level2 || {}).level3;
                              var r2 = (((test || {}).level1 || {}).level2 || {}).foo;


                              Original solution (suggested in question) – 45%



                              var r1 = test.level1 && test.level1.level2 && test.level1.level2.level3;
                              var r2 = test.level1 && test.level1.level2 && test.level1.level2.foo;


                              checkNested – 50%



                              function checkNested(obj) {
                              for (var i = 1; i < arguments.length; i++) {
                              if (!obj.hasOwnProperty(arguments[i])) {
                              return false;
                              }
                              obj = obj[arguments[i]];
                              }
                              return true;
                              }


                              get_if_exist – 52%



                              function get_if_exist(str) {
                              try { return eval(str) }
                              catch(e) { return undefined }
                              }


                              validChain – 54%



                              function validChain( object, ...keys ) {
                              return keys.reduce( ( a, b ) => ( a || { } )[ b ], object ) !== undefined;
                              }


                              objHasKeys – 63%



                              function objHasKeys(obj, keys) {
                              var next = keys.shift();
                              return obj[next] && (! keys.length || objHasKeys(obj[next], keys));
                              }


                              nestedPropertyExists – 69%



                              function nestedPropertyExists(obj, props) {
                              var prop = props.shift();
                              return prop === undefined ? true : obj.hasOwnProperty(prop) ? nestedPropertyExists(obj[prop], props) : false;
                              }


                              _.get – 72%



                              deeptest – 86%



                              function deeptest(target, s){
                              s= s.split('.')
                              var obj= target[s.shift()];
                              while(obj && s.length) obj= obj[s.shift()];
                              return obj;
                              }


                              sad clowns – 100% – slowest



                              var o = function(obj) { return obj || {} };

                              var r1 = o(o(o(o(test).level1).level2).level3);
                              var r2 = o(o(o(o(test).level1).level2).foo);





                              share|improve this answer



















                              • 12




                                it should be noted that the more % a test has - the SLOWER it is
                                – avalanche1
                                Feb 3 '17 at 9:12






                              • 1




                                what about lodash _.get() ? how performant is it comparing to those answers?
                                – beniutek
                                May 31 '17 at 14:07






                              • 3




                                Tests with _.get() - jsben.ch/7aJgK
                                – cdMinix
                                Jun 27 '17 at 7:47








                              • 1




                                Each method of these is slower or faster than other ones depending on situation. If all keys are found then "Object Wrap" could be fastest, but if one of the keys is not found then "Native solution/Original solution" could be faster.
                                – evilReiko
                                Aug 28 '17 at 6:55






                              • 1




                                @evilReiko Any method will be slower if no keys are found but in proportion to each other it's still pretty much the same. However, you are right – this is more of an intellectual exercise than anything else. We are talking about a million iterations per millisecond here. I see no use case where it would make much difference. Me personally I would go for reduce or try/catch out of convenience.
                                – unitario
                                Aug 30 '17 at 6:36













                              up vote
                              141
                              down vote










                              up vote
                              141
                              down vote









                              I have done performance tests (thank you cdMinix for adding lodash) on some of the suggestions proposed to this question with the results listed below.




                              Disclaimer #1 Turning strings into references is unnecessary meta-programming and probably best avoided. Don't lose track of your references to begin with. Read more from this answer to a similar question.



                              Disclaimer #2 We are talking about millions of operations per millisecond here. It is very unlikely any of these would make much difference in most use cases. Choose whichever makes the most sense knowing the limitations of each. For me I would go with something like reduce out of convenience.




                              Object Wrap (by Oliver Steele) – 34 % – fastest



                              var r1 = (((test || {}).level1 || {}).level2 || {}).level3;
                              var r2 = (((test || {}).level1 || {}).level2 || {}).foo;


                              Original solution (suggested in question) – 45%



                              var r1 = test.level1 && test.level1.level2 && test.level1.level2.level3;
                              var r2 = test.level1 && test.level1.level2 && test.level1.level2.foo;


                              checkNested – 50%



                              function checkNested(obj) {
                              for (var i = 1; i < arguments.length; i++) {
                              if (!obj.hasOwnProperty(arguments[i])) {
                              return false;
                              }
                              obj = obj[arguments[i]];
                              }
                              return true;
                              }


                              get_if_exist – 52%



                              function get_if_exist(str) {
                              try { return eval(str) }
                              catch(e) { return undefined }
                              }


                              validChain – 54%



                              function validChain( object, ...keys ) {
                              return keys.reduce( ( a, b ) => ( a || { } )[ b ], object ) !== undefined;
                              }


                              objHasKeys – 63%



                              function objHasKeys(obj, keys) {
                              var next = keys.shift();
                              return obj[next] && (! keys.length || objHasKeys(obj[next], keys));
                              }


                              nestedPropertyExists – 69%



                              function nestedPropertyExists(obj, props) {
                              var prop = props.shift();
                              return prop === undefined ? true : obj.hasOwnProperty(prop) ? nestedPropertyExists(obj[prop], props) : false;
                              }


                              _.get – 72%



                              deeptest – 86%



                              function deeptest(target, s){
                              s= s.split('.')
                              var obj= target[s.shift()];
                              while(obj && s.length) obj= obj[s.shift()];
                              return obj;
                              }


                              sad clowns – 100% – slowest



                              var o = function(obj) { return obj || {} };

                              var r1 = o(o(o(o(test).level1).level2).level3);
                              var r2 = o(o(o(o(test).level1).level2).foo);





                              share|improve this answer














                              I have done performance tests (thank you cdMinix for adding lodash) on some of the suggestions proposed to this question with the results listed below.




                              Disclaimer #1 Turning strings into references is unnecessary meta-programming and probably best avoided. Don't lose track of your references to begin with. Read more from this answer to a similar question.



                              Disclaimer #2 We are talking about millions of operations per millisecond here. It is very unlikely any of these would make much difference in most use cases. Choose whichever makes the most sense knowing the limitations of each. For me I would go with something like reduce out of convenience.




                              Object Wrap (by Oliver Steele) – 34 % – fastest



                              var r1 = (((test || {}).level1 || {}).level2 || {}).level3;
                              var r2 = (((test || {}).level1 || {}).level2 || {}).foo;


                              Original solution (suggested in question) – 45%



                              var r1 = test.level1 && test.level1.level2 && test.level1.level2.level3;
                              var r2 = test.level1 && test.level1.level2 && test.level1.level2.foo;


                              checkNested – 50%



                              function checkNested(obj) {
                              for (var i = 1; i < arguments.length; i++) {
                              if (!obj.hasOwnProperty(arguments[i])) {
                              return false;
                              }
                              obj = obj[arguments[i]];
                              }
                              return true;
                              }


                              get_if_exist – 52%



                              function get_if_exist(str) {
                              try { return eval(str) }
                              catch(e) { return undefined }
                              }


                              validChain – 54%



                              function validChain( object, ...keys ) {
                              return keys.reduce( ( a, b ) => ( a || { } )[ b ], object ) !== undefined;
                              }


                              objHasKeys – 63%



                              function objHasKeys(obj, keys) {
                              var next = keys.shift();
                              return obj[next] && (! keys.length || objHasKeys(obj[next], keys));
                              }


                              nestedPropertyExists – 69%



                              function nestedPropertyExists(obj, props) {
                              var prop = props.shift();
                              return prop === undefined ? true : obj.hasOwnProperty(prop) ? nestedPropertyExists(obj[prop], props) : false;
                              }


                              _.get – 72%



                              deeptest – 86%



                              function deeptest(target, s){
                              s= s.split('.')
                              var obj= target[s.shift()];
                              while(obj && s.length) obj= obj[s.shift()];
                              return obj;
                              }


                              sad clowns – 100% – slowest



                              var o = function(obj) { return obj || {} };

                              var r1 = o(o(o(o(test).level1).level2).level3);
                              var r2 = o(o(o(o(test).level1).level2).foo);






                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              edited Oct 10 '17 at 20:37









                              Necreaux

                              6,50171940




                              6,50171940










                              answered Jan 8 '17 at 11:56









                              unitario

                              3,00932032




                              3,00932032








                              • 12




                                it should be noted that the more % a test has - the SLOWER it is
                                – avalanche1
                                Feb 3 '17 at 9:12






                              • 1




                                what about lodash _.get() ? how performant is it comparing to those answers?
                                – beniutek
                                May 31 '17 at 14:07






                              • 3




                                Tests with _.get() - jsben.ch/7aJgK
                                – cdMinix
                                Jun 27 '17 at 7:47








                              • 1




                                Each method of these is slower or faster than other ones depending on situation. If all keys are found then "Object Wrap" could be fastest, but if one of the keys is not found then "Native solution/Original solution" could be faster.
                                – evilReiko
                                Aug 28 '17 at 6:55






                              • 1




                                @evilReiko Any method will be slower if no keys are found but in proportion to each other it's still pretty much the same. However, you are right – this is more of an intellectual exercise than anything else. We are talking about a million iterations per millisecond here. I see no use case where it would make much difference. Me personally I would go for reduce or try/catch out of convenience.
                                – unitario
                                Aug 30 '17 at 6:36














                              • 12




                                it should be noted that the more % a test has - the SLOWER it is
                                – avalanche1
                                Feb 3 '17 at 9:12






                              • 1




                                what about lodash _.get() ? how performant is it comparing to those answers?
                                – beniutek
                                May 31 '17 at 14:07






                              • 3




                                Tests with _.get() - jsben.ch/7aJgK
                                – cdMinix
                                Jun 27 '17 at 7:47








                              • 1




                                Each method of these is slower or faster than other ones depending on situation. If all keys are found then "Object Wrap" could be fastest, but if one of the keys is not found then "Native solution/Original solution" could be faster.
                                – evilReiko
                                Aug 28 '17 at 6:55






                              • 1




                                @evilReiko Any method will be slower if no keys are found but in proportion to each other it's still pretty much the same. However, you are right – this is more of an intellectual exercise than anything else. We are talking about a million iterations per millisecond here. I see no use case where it would make much difference. Me personally I would go for reduce or try/catch out of convenience.
                                – unitario
                                Aug 30 '17 at 6:36








                              12




                              12




                              it should be noted that the more % a test has - the SLOWER it is
                              – avalanche1
                              Feb 3 '17 at 9:12




                              it should be noted that the more % a test has - the SLOWER it is
                              – avalanche1
                              Feb 3 '17 at 9:12




                              1




                              1




                              what about lodash _.get() ? how performant is it comparing to those answers?
                              – beniutek
                              May 31 '17 at 14:07




                              what about lodash _.get() ? how performant is it comparing to those answers?
                              – beniutek
                              May 31 '17 at 14:07




                              3




                              3




                              Tests with _.get() - jsben.ch/7aJgK
                              – cdMinix
                              Jun 27 '17 at 7:47






                              Tests with _.get() - jsben.ch/7aJgK
                              – cdMinix
                              Jun 27 '17 at 7:47






                              1




                              1




                              Each method of these is slower or faster than other ones depending on situation. If all keys are found then "Object Wrap" could be fastest, but if one of the keys is not found then "Native solution/Original solution" could be faster.
                              – evilReiko
                              Aug 28 '17 at 6:55




                              Each method of these is slower or faster than other ones depending on situation. If all keys are found then "Object Wrap" could be fastest, but if one of the keys is not found then "Native solution/Original solution" could be faster.
                              – evilReiko
                              Aug 28 '17 at 6:55




                              1




                              1




                              @evilReiko Any method will be slower if no keys are found but in proportion to each other it's still pretty much the same. However, you are right – this is more of an intellectual exercise than anything else. We are talking about a million iterations per millisecond here. I see no use case where it would make much difference. Me personally I would go for reduce or try/catch out of convenience.
                              – unitario
                              Aug 30 '17 at 6:36




                              @evilReiko Any method will be slower if no keys are found but in proportion to each other it's still pretty much the same. However, you are right – this is more of an intellectual exercise than anything else. We are talking about a million iterations per millisecond here. I see no use case where it would make much difference. Me personally I would go for reduce or try/catch out of convenience.
                              – unitario
                              Aug 30 '17 at 6:36










                              up vote
                              41
                              down vote













                              You can read an object property at any depth, if you handle the name like a string: 't.level1.level2.level3'.



                              window.t={level1:{level2:{level3: 'level3'}}};

                              function deeptest(s){
                              s= s.split('.')
                              var obj= window[s.shift()];
                              while(obj && s.length) obj= obj[s.shift()];
                              return obj;
                              }

                              alert(deeptest('t.level1.level2.level3') || 'Undefined');


                              It returns undefined if any of the segments is undefined.






                              share|improve this answer



















                              • 3




                                Worth noting that this method is very performant, at least in Chrome, in some cases outperforming @Claudiu modified version of selected answer. See performance test here: jsperf.com/check-if-deep-property-exists-with-willnotthrow
                                – netpoetica
                                Nov 27 '14 at 5:32















                              up vote
                              41
                              down vote













                              You can read an object property at any depth, if you handle the name like a string: 't.level1.level2.level3'.



                              window.t={level1:{level2:{level3: 'level3'}}};

                              function deeptest(s){
                              s= s.split('.')
                              var obj= window[s.shift()];
                              while(obj && s.length) obj= obj[s.shift()];
                              return obj;
                              }

                              alert(deeptest('t.level1.level2.level3') || 'Undefined');


                              It returns undefined if any of the segments is undefined.






                              share|improve this answer



















                              • 3




                                Worth noting that this method is very performant, at least in Chrome, in some cases outperforming @Claudiu modified version of selected answer. See performance test here: jsperf.com/check-if-deep-property-exists-with-willnotthrow
                                – netpoetica
                                Nov 27 '14 at 5:32













                              up vote
                              41
                              down vote










                              up vote
                              41
                              down vote









                              You can read an object property at any depth, if you handle the name like a string: 't.level1.level2.level3'.



                              window.t={level1:{level2:{level3: 'level3'}}};

                              function deeptest(s){
                              s= s.split('.')
                              var obj= window[s.shift()];
                              while(obj && s.length) obj= obj[s.shift()];
                              return obj;
                              }

                              alert(deeptest('t.level1.level2.level3') || 'Undefined');


                              It returns undefined if any of the segments is undefined.






                              share|improve this answer














                              You can read an object property at any depth, if you handle the name like a string: 't.level1.level2.level3'.



                              window.t={level1:{level2:{level3: 'level3'}}};

                              function deeptest(s){
                              s= s.split('.')
                              var obj= window[s.shift()];
                              while(obj && s.length) obj= obj[s.shift()];
                              return obj;
                              }

                              alert(deeptest('t.level1.level2.level3') || 'Undefined');


                              It returns undefined if any of the segments is undefined.







                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              edited Nov 28 '14 at 0:49

























                              answered Apr 13 '10 at 16:56









                              kennebec

                              77.7k1886115




                              77.7k1886115








                              • 3




                                Worth noting that this method is very performant, at least in Chrome, in some cases outperforming @Claudiu modified version of selected answer. See performance test here: jsperf.com/check-if-deep-property-exists-with-willnotthrow
                                – netpoetica
                                Nov 27 '14 at 5:32














                              • 3




                                Worth noting that this method is very performant, at least in Chrome, in some cases outperforming @Claudiu modified version of selected answer. See performance test here: jsperf.com/check-if-deep-property-exists-with-willnotthrow
                                – netpoetica
                                Nov 27 '14 at 5:32








                              3




                              3




                              Worth noting that this method is very performant, at least in Chrome, in some cases outperforming @Claudiu modified version of selected answer. See performance test here: jsperf.com/check-if-deep-property-exists-with-willnotthrow
                              – netpoetica
                              Nov 27 '14 at 5:32




                              Worth noting that this method is very performant, at least in Chrome, in some cases outperforming @Claudiu modified version of selected answer. See performance test here: jsperf.com/check-if-deep-property-exists-with-willnotthrow
                              – netpoetica
                              Nov 27 '14 at 5:32










                              up vote
                              23
                              down vote













                              var a;

                              a = {
                              b: {
                              c: 'd'
                              }
                              };

                              function isset (fn) {
                              var value;
                              try {
                              value = fn();
                              } catch (e) {
                              value = undefined;
                              } finally {
                              return value !== undefined;
                              }
                              };

                              // ES5
                              console.log(
                              isset(function () { return a.b.c; }),
                              isset(function () { return a.b.c.d.e.f; })
                              );


                              If you are coding in ES6 environment (or using 6to5) then you can take advantage of the arrow function syntax:



                              // ES6 using the arrow function
                              console.log(
                              isset(() => a.b.c),
                              isset(() => a.b.c.d.e.f)
                              );


                              Regarding the performance, there is no performance penalty for using try..catch block if the property is set. There is a performance impact if the property is unset.



                              Consider simply using _.has:



                              var object = { 'a': { 'b': { 'c': 3 } } };

                              _.has(object, 'a');
                              // → true

                              _.has(object, 'a.b.c');
                              // → true

                              _.has(object, ['a', 'b', 'c']);
                              // → true





                              share|improve this answer



















                              • 2




                                I think the try-catch approach is the best answer. There's a philosophical difference between querying an object for its type, and assuming the API exists and failing accordingly if it doesn't. The latter is more appropriate in loosely typed languages. See stackoverflow.com/a/408305/2419669. The try-catch approach is also far clearer than if (foo && foo.bar && foo.bar.baz && foo.bar.baz.qux) { ... }.
                                – yangmillstheory
                                Jan 31 '16 at 3:39












                              • Out of all the answers on StackOverflow, this answer actually worked. And i tried them all for various nested object properties and key values existence checks. Thanks!
                                – Jonathan Marzullo
                                Jul 19 '16 at 15:30















                              up vote
                              23
                              down vote













                              var a;

                              a = {
                              b: {
                              c: 'd'
                              }
                              };

                              function isset (fn) {
                              var value;
                              try {
                              value = fn();
                              } catch (e) {
                              value = undefined;
                              } finally {
                              return value !== undefined;
                              }
                              };

                              // ES5
                              console.log(
                              isset(function () { return a.b.c; }),
                              isset(function () { return a.b.c.d.e.f; })
                              );


                              If you are coding in ES6 environment (or using 6to5) then you can take advantage of the arrow function syntax:



                              // ES6 using the arrow function
                              console.log(
                              isset(() => a.b.c),
                              isset(() => a.b.c.d.e.f)
                              );


                              Regarding the performance, there is no performance penalty for using try..catch block if the property is set. There is a performance impact if the property is unset.



                              Consider simply using _.has:



                              var object = { 'a': { 'b': { 'c': 3 } } };

                              _.has(object, 'a');
                              // → true

                              _.has(object, 'a.b.c');
                              // → true

                              _.has(object, ['a', 'b', 'c']);
                              // → true





                              share|improve this answer



















                              • 2




                                I think the try-catch approach is the best answer. There's a philosophical difference between querying an object for its type, and assuming the API exists and failing accordingly if it doesn't. The latter is more appropriate in loosely typed languages. See stackoverflow.com/a/408305/2419669. The try-catch approach is also far clearer than if (foo && foo.bar && foo.bar.baz && foo.bar.baz.qux) { ... }.
                                – yangmillstheory
                                Jan 31 '16 at 3:39












                              • Out of all the answers on StackOverflow, this answer actually worked. And i tried them all for various nested object properties and key values existence checks. Thanks!
                                – Jonathan Marzullo
                                Jul 19 '16 at 15:30













                              up vote
                              23
                              down vote










                              up vote
                              23
                              down vote









                              var a;

                              a = {
                              b: {
                              c: 'd'
                              }
                              };

                              function isset (fn) {
                              var value;
                              try {
                              value = fn();
                              } catch (e) {
                              value = undefined;
                              } finally {
                              return value !== undefined;
                              }
                              };

                              // ES5
                              console.log(
                              isset(function () { return a.b.c; }),
                              isset(function () { return a.b.c.d.e.f; })
                              );


                              If you are coding in ES6 environment (or using 6to5) then you can take advantage of the arrow function syntax:



                              // ES6 using the arrow function
                              console.log(
                              isset(() => a.b.c),
                              isset(() => a.b.c.d.e.f)
                              );


                              Regarding the performance, there is no performance penalty for using try..catch block if the property is set. There is a performance impact if the property is unset.



                              Consider simply using _.has:



                              var object = { 'a': { 'b': { 'c': 3 } } };

                              _.has(object, 'a');
                              // → true

                              _.has(object, 'a.b.c');
                              // → true

                              _.has(object, ['a', 'b', 'c']);
                              // → true





                              share|improve this answer














                              var a;

                              a = {
                              b: {
                              c: 'd'
                              }
                              };

                              function isset (fn) {
                              var value;
                              try {
                              value = fn();
                              } catch (e) {
                              value = undefined;
                              } finally {
                              return value !== undefined;
                              }
                              };

                              // ES5
                              console.log(
                              isset(function () { return a.b.c; }),
                              isset(function () { return a.b.c.d.e.f; })
                              );


                              If you are coding in ES6 environment (or using 6to5) then you can take advantage of the arrow function syntax:



                              // ES6 using the arrow function
                              console.log(
                              isset(() => a.b.c),
                              isset(() => a.b.c.d.e.f)
                              );


                              Regarding the performance, there is no performance penalty for using try..catch block if the property is set. There is a performance impact if the property is unset.



                              Consider simply using _.has:



                              var object = { 'a': { 'b': { 'c': 3 } } };

                              _.has(object, 'a');
                              // → true

                              _.has(object, 'a.b.c');
                              // → true

                              _.has(object, ['a', 'b', 'c']);
                              // → true






                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              edited Jan 31 '16 at 13:06

























                              answered Nov 18 '14 at 9:06









                              Gajus

                              28.8k35172311




                              28.8k35172311








                              • 2




                                I think the try-catch approach is the best answer. There's a philosophical difference between querying an object for its type, and assuming the API exists and failing accordingly if it doesn't. The latter is more appropriate in loosely typed languages. See stackoverflow.com/a/408305/2419669. The try-catch approach is also far clearer than if (foo && foo.bar && foo.bar.baz && foo.bar.baz.qux) { ... }.
                                – yangmillstheory
                                Jan 31 '16 at 3:39












                              • Out of all the answers on StackOverflow, this answer actually worked. And i tried them all for various nested object properties and key values existence checks. Thanks!
                                – Jonathan Marzullo
                                Jul 19 '16 at 15:30














                              • 2




                                I think the try-catch approach is the best answer. There's a philosophical difference between querying an object for its type, and assuming the API exists and failing accordingly if it doesn't. The latter is more appropriate in loosely typed languages. See stackoverflow.com/a/408305/2419669. The try-catch approach is also far clearer than if (foo && foo.bar && foo.bar.baz && foo.bar.baz.qux) { ... }.
                                – yangmillstheory
                                Jan 31 '16 at 3:39












                              • Out of all the answers on StackOverflow, this answer actually worked. And i tried them all for various nested object properties and key values existence checks. Thanks!
                                – Jonathan Marzullo
                                Jul 19 '16 at 15:30








                              2




                              2




                              I think the try-catch approach is the best answer. There's a philosophical difference between querying an object for its type, and assuming the API exists and failing accordingly if it doesn't. The latter is more appropriate in loosely typed languages. See stackoverflow.com/a/408305/2419669. The try-catch approach is also far clearer than if (foo && foo.bar && foo.bar.baz && foo.bar.baz.qux) { ... }.
                              – yangmillstheory
                              Jan 31 '16 at 3:39






                              I think the try-catch approach is the best answer. There's a philosophical difference between querying an object for its type, and assuming the API exists and failing accordingly if it doesn't. The latter is more appropriate in loosely typed languages. See stackoverflow.com/a/408305/2419669. The try-catch approach is also far clearer than if (foo && foo.bar && foo.bar.baz && foo.bar.baz.qux) { ... }.
                              – yangmillstheory
                              Jan 31 '16 at 3:39














                              Out of all the answers on StackOverflow, this answer actually worked. And i tried them all for various nested object properties and key values existence checks. Thanks!
                              – Jonathan Marzullo
                              Jul 19 '16 at 15:30




                              Out of all the answers on StackOverflow, this answer actually worked. And i tried them all for various nested object properties and key values existence checks. Thanks!
                              – Jonathan Marzullo
                              Jul 19 '16 at 15:30










                              up vote
                              17
                              down vote













                              how about



                              try {
                              alert(test.level1.level2.level3)
                              } catch(e) {
                              ...whatever

                              }





                              share|improve this answer

















                              • 13




                                I don't think try/catch is a good way to test for existence of an object: try/catch is meant to handle exceptions, not normal conditions such as the test here. I think (typeof foo == "undefined") at each step is better -- and in general, there's probably some refactoring required if you're working with such deeply nested properties. Also, try/catch will cause a break in Firebug (and in any browser where break-on-error is turned on) if an exception is thrown.
                                – Sam Dutton
                                Nov 9 '10 at 12:00










                              • I vote on this, because browser will check the existence twice if you use other solutions. Lets say you want to call ´a.c.b = 2´. Browser has to check the existence before modifying the value (otherwise it would be a memory error caught by OS).
                                – user669677
                                Sep 2 '13 at 12:04






                              • 4




                                The question still remain: witch one is faster for browsers to set up a try catch or call hasOwnProperty() n times?
                                – user669677
                                Sep 2 '13 at 12:12








                              • 12




                                Why is this bad again? This looks cleanest to me.
                                – Austin Pray
                                Jun 4 '14 at 19:26










                              • I would say: If you expect that the property exist than it is okay to wrap it into a try block. If it then doesn't exist it is an error. But if you're just lazy and put regular code into the catch block for the case that the property doesn't exist try/catch is misused. Here a if/else or something similar is required.
                                – robsch
                                Aug 9 '16 at 13:55















                              up vote
                              17
                              down vote













                              how about



                              try {
                              alert(test.level1.level2.level3)
                              } catch(e) {
                              ...whatever

                              }





                              share|improve this answer

















                              • 13




                                I don't think try/catch is a good way to test for existence of an object: try/catch is meant to handle exceptions, not normal conditions such as the test here. I think (typeof foo == "undefined") at each step is better -- and in general, there's probably some refactoring required if you're working with such deeply nested properties. Also, try/catch will cause a break in Firebug (and in any browser where break-on-error is turned on) if an exception is thrown.
                                – Sam Dutton
                                Nov 9 '10 at 12:00










                              • I vote on this, because browser will check the existence twice if you use other solutions. Lets say you want to call ´a.c.b = 2´. Browser has to check the existence before modifying the value (otherwise it would be a memory error caught by OS).
                                – user669677
                                Sep 2 '13 at 12:04






                              • 4




                                The question still remain: witch one is faster for browsers to set up a try catch or call hasOwnProperty() n times?
                                – user669677
                                Sep 2 '13 at 12:12








                              • 12




                                Why is this bad again? This looks cleanest to me.
                                – Austin Pray
                                Jun 4 '14 at 19:26










                              • I would say: If you expect that the property exist than it is okay to wrap it into a try block. If it then doesn't exist it is an error. But if you're just lazy and put regular code into the catch block for the case that the property doesn't exist try/catch is misused. Here a if/else or something similar is required.
                                – robsch
                                Aug 9 '16 at 13:55













                              up vote
                              17
                              down vote










                              up vote
                              17
                              down vote









                              how about



                              try {
                              alert(test.level1.level2.level3)
                              } catch(e) {
                              ...whatever

                              }





                              share|improve this answer












                              how about



                              try {
                              alert(test.level1.level2.level3)
                              } catch(e) {
                              ...whatever

                              }






                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered Apr 13 '10 at 16:09









                              user187291

                              45k1677126




                              45k1677126








                              • 13




                                I don't think try/catch is a good way to test for existence of an object: try/catch is meant to handle exceptions, not normal conditions such as the test here. I think (typeof foo == "undefined") at each step is better -- and in general, there's probably some refactoring required if you're working with such deeply nested properties. Also, try/catch will cause a break in Firebug (and in any browser where break-on-error is turned on) if an exception is thrown.
                                – Sam Dutton
                                Nov 9 '10 at 12:00










                              • I vote on this, because browser will check the existence twice if you use other solutions. Lets say you want to call ´a.c.b = 2´. Browser has to check the existence before modifying the value (otherwise it would be a memory error caught by OS).
                                – user669677
                                Sep 2 '13 at 12:04






                              • 4




                                The question still remain: witch one is faster for browsers to set up a try catch or call hasOwnProperty() n times?
                                – user669677
                                Sep 2 '13 at 12:12








                              • 12




                                Why is this bad again? This looks cleanest to me.
                                – Austin Pray
                                Jun 4 '14 at 19:26










                              • I would say: If you expect that the property exist than it is okay to wrap it into a try block. If it then doesn't exist it is an error. But if you're just lazy and put regular code into the catch block for the case that the property doesn't exist try/catch is misused. Here a if/else or something similar is required.
                                – robsch
                                Aug 9 '16 at 13:55














                              • 13




                                I don't think try/catch is a good way to test for existence of an object: try/catch is meant to handle exceptions, not normal conditions such as the test here. I think (typeof foo == "undefined") at each step is better -- and in general, there's probably some refactoring required if you're working with such deeply nested properties. Also, try/catch will cause a break in Firebug (and in any browser where break-on-error is turned on) if an exception is thrown.
                                – Sam Dutton
                                Nov 9 '10 at 12:00










                              • I vote on this, because browser will check the existence twice if you use other solutions. Lets say you want to call ´a.c.b = 2´. Browser has to check the existence before modifying the value (otherwise it would be a memory error caught by OS).
                                – user669677
                                Sep 2 '13 at 12:04






                              • 4




                                The question still remain: witch one is faster for browsers to set up a try catch or call hasOwnProperty() n times?
                                – user669677
                                Sep 2 '13 at 12:12








                              • 12




                                Why is this bad again? This looks cleanest to me.
                                – Austin Pray
                                Jun 4 '14 at 19:26










                              • I would say: If you expect that the property exist than it is okay to wrap it into a try block. If it then doesn't exist it is an error. But if you're just lazy and put regular code into the catch block for the case that the property doesn't exist try/catch is misused. Here a if/else or something similar is required.
                                – robsch
                                Aug 9 '16 at 13:55








                              13




                              13




                              I don't think try/catch is a good way to test for existence of an object: try/catch is meant to handle exceptions, not normal conditions such as the test here. I think (typeof foo == "undefined") at each step is better -- and in general, there's probably some refactoring required if you're working with such deeply nested properties. Also, try/catch will cause a break in Firebug (and in any browser where break-on-error is turned on) if an exception is thrown.
                              – Sam Dutton
                              Nov 9 '10 at 12:00




                              I don't think try/catch is a good way to test for existence of an object: try/catch is meant to handle exceptions, not normal conditions such as the test here. I think (typeof foo == "undefined") at each step is better -- and in general, there's probably some refactoring required if you're working with such deeply nested properties. Also, try/catch will cause a break in Firebug (and in any browser where break-on-error is turned on) if an exception is thrown.
                              – Sam Dutton
                              Nov 9 '10 at 12:00












                              I vote on this, because browser will check the existence twice if you use other solutions. Lets say you want to call ´a.c.b = 2´. Browser has to check the existence before modifying the value (otherwise it would be a memory error caught by OS).
                              – user669677
                              Sep 2 '13 at 12:04




                              I vote on this, because browser will check the existence twice if you use other solutions. Lets say you want to call ´a.c.b = 2´. Browser has to check the existence before modifying the value (otherwise it would be a memory error caught by OS).
                              – user669677
                              Sep 2 '13 at 12:04




                              4




                              4




                              The question still remain: witch one is faster for browsers to set up a try catch or call hasOwnProperty() n times?
                              – user669677
                              Sep 2 '13 at 12:12






                              The question still remain: witch one is faster for browsers to set up a try catch or call hasOwnProperty() n times?
                              – user669677
                              Sep 2 '13 at 12:12






                              12




                              12




                              Why is this bad again? This looks cleanest to me.
                              – Austin Pray
                              Jun 4 '14 at 19:26




                              Why is this bad again? This looks cleanest to me.
                              – Austin Pray
                              Jun 4 '14 at 19:26












                              I would say: If you expect that the property exist than it is okay to wrap it into a try block. If it then doesn't exist it is an error. But if you're just lazy and put regular code into the catch block for the case that the property doesn't exist try/catch is misused. Here a if/else or something similar is required.
                              – robsch
                              Aug 9 '16 at 13:55




                              I would say: If you expect that the property exist than it is okay to wrap it into a try block. If it then doesn't exist it is an error. But if you're just lazy and put regular code into the catch block for the case that the property doesn't exist try/catch is misused. Here a if/else or something similar is required.
                              – robsch
                              Aug 9 '16 at 13:55










                              up vote
                              9
                              down vote













                              ES6 answer, thoroughly tested :)



                              const propExists = (obj, path) => {
                              return !!path.split('.').reduce((obj, prop) => {
                              return obj && obj[prop] ? obj[prop] : undefined;
                              }, obj)
                              }


                              →see Codepen with full test coverage






                              share|improve this answer





















                              • I made your tests failed setting the value of the flat prop to 0. You must care about type coercion.
                                – germain
                                Oct 2 at 7:13










                              • @germain Does this work for you? (I explicitly compare === for the different falsys, and added test. If you have a better idea, let me know).
                                – Frank Nocke
                                Oct 2 at 11:22










                              • I made your tests failed again setting the value of the flat prop to false. And then you might want to have a value in your object set to undefined (I know it's weird but is is JS). I made a positive false value set to 'Prop not Found': const hasTruthyProp = prop => prop === 'Prop not found' ? false : true const path = obj => path => path.reduce((obj, prop) => { return obj && obj.hasOwnProperty(prop) ? obj[prop] : 'Prop not found' }, obj) const myFunc = compose(hasTruthyProp, path(obj))
                                – germain
                                Oct 2 at 15:19












                              • Can you fork my codepen (top-right, easy), correct & add tests, and send me the URL of yours? Thanks =)
                                – Frank Nocke
                                Oct 3 at 18:16










                              • Check this
                                – germain
                                Oct 4 at 5:01















                              up vote
                              9
                              down vote













                              ES6 answer, thoroughly tested :)



                              const propExists = (obj, path) => {
                              return !!path.split('.').reduce((obj, prop) => {
                              return obj && obj[prop] ? obj[prop] : undefined;
                              }, obj)
                              }


                              →see Codepen with full test coverage






                              share|improve this answer





















                              • I made your tests failed setting the value of the flat prop to 0. You must care about type coercion.
                                – germain
                                Oct 2 at 7:13










                              • @germain Does this work for you? (I explicitly compare === for the different falsys, and added test. If you have a better idea, let me know).
                                – Frank Nocke
                                Oct 2 at 11:22










                              • I made your tests failed again setting the value of the flat prop to false. And then you might want to have a value in your object set to undefined (I know it's weird but is is JS). I made a positive false value set to 'Prop not Found': const hasTruthyProp = prop => prop === 'Prop not found' ? false : true const path = obj => path => path.reduce((obj, prop) => { return obj && obj.hasOwnProperty(prop) ? obj[prop] : 'Prop not found' }, obj) const myFunc = compose(hasTruthyProp, path(obj))
                                – germain
                                Oct 2 at 15:19












                              • Can you fork my codepen (top-right, easy), correct & add tests, and send me the URL of yours? Thanks =)
                                – Frank Nocke
                                Oct 3 at 18:16










                              • Check this
                                – germain
                                Oct 4 at 5:01













                              up vote
                              9
                              down vote










                              up vote
                              9
                              down vote









                              ES6 answer, thoroughly tested :)



                              const propExists = (obj, path) => {
                              return !!path.split('.').reduce((obj, prop) => {
                              return obj && obj[prop] ? obj[prop] : undefined;
                              }, obj)
                              }


                              →see Codepen with full test coverage






                              share|improve this answer












                              ES6 answer, thoroughly tested :)



                              const propExists = (obj, path) => {
                              return !!path.split('.').reduce((obj, prop) => {
                              return obj && obj[prop] ? obj[prop] : undefined;
                              }, obj)
                              }


                              →see Codepen with full test coverage







                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered May 31 at 12:58









                              Frank Nocke

                              4,1873659




                              4,1873659












                              • I made your tests failed setting the value of the flat prop to 0. You must care about type coercion.
                                – germain
                                Oct 2 at 7:13










                              • @germain Does this work for you? (I explicitly compare === for the different falsys, and added test. If you have a better idea, let me know).
                                – Frank Nocke
                                Oct 2 at 11:22










                              • I made your tests failed again setting the value of the flat prop to false. And then you might want to have a value in your object set to undefined (I know it's weird but is is JS). I made a positive false value set to 'Prop not Found': const hasTruthyProp = prop => prop === 'Prop not found' ? false : true const path = obj => path => path.reduce((obj, prop) => { return obj && obj.hasOwnProperty(prop) ? obj[prop] : 'Prop not found' }, obj) const myFunc = compose(hasTruthyProp, path(obj))
                                – germain
                                Oct 2 at 15:19












                              • Can you fork my codepen (top-right, easy), correct & add tests, and send me the URL of yours? Thanks =)
                                – Frank Nocke
                                Oct 3 at 18:16










                              • Check this
                                – germain
                                Oct 4 at 5:01


















                              • I made your tests failed setting the value of the flat prop to 0. You must care about type coercion.
                                – germain
                                Oct 2 at 7:13










                              • @germain Does this work for you? (I explicitly compare === for the different falsys, and added test. If you have a better idea, let me know).
                                – Frank Nocke
                                Oct 2 at 11:22










                              • I made your tests failed again setting the value of the flat prop to false. And then you might want to have a value in your object set to undefined (I know it's weird but is is JS). I made a positive false value set to 'Prop not Found': const hasTruthyProp = prop => prop === 'Prop not found' ? false : true const path = obj => path => path.reduce((obj, prop) => { return obj && obj.hasOwnProperty(prop) ? obj[prop] : 'Prop not found' }, obj) const myFunc = compose(hasTruthyProp, path(obj))
                                – germain
                                Oct 2 at 15:19












                              • Can you fork my codepen (top-right, easy), correct & add tests, and send me the URL of yours? Thanks =)
                                – Frank Nocke
                                Oct 3 at 18:16










                              • Check this
                                – germain
                                Oct 4 at 5:01
















                              I made your tests failed setting the value of the flat prop to 0. You must care about type coercion.
                              – germain
                              Oct 2 at 7:13




                              I made your tests failed setting the value of the flat prop to 0. You must care about type coercion.
                              – germain
                              Oct 2 at 7:13












                              @germain Does this work for you? (I explicitly compare === for the different falsys, and added test. If you have a better idea, let me know).
                              – Frank Nocke
                              Oct 2 at 11:22




                              @germain Does this work for you? (I explicitly compare === for the different falsys, and added test. If you have a better idea, let me know).
                              – Frank Nocke
                              Oct 2 at 11:22












                              I made your tests failed again setting the value of the flat prop to false. And then you might want to have a value in your object set to undefined (I know it's weird but is is JS). I made a positive false value set to 'Prop not Found': const hasTruthyProp = prop => prop === 'Prop not found' ? false : true const path = obj => path => path.reduce((obj, prop) => { return obj && obj.hasOwnProperty(prop) ? obj[prop] : 'Prop not found' }, obj) const myFunc = compose(hasTruthyProp, path(obj))
                              – germain
                              Oct 2 at 15:19






                              I made your tests failed again setting the value of the flat prop to false. And then you might want to have a value in your object set to undefined (I know it's weird but is is JS). I made a positive false value set to 'Prop not Found': const hasTruthyProp = prop => prop === 'Prop not found' ? false : true const path = obj => path => path.reduce((obj, prop) => { return obj && obj.hasOwnProperty(prop) ? obj[prop] : 'Prop not found' }, obj) const myFunc = compose(hasTruthyProp, path(obj))
                              – germain
                              Oct 2 at 15:19














                              Can you fork my codepen (top-right, easy), correct & add tests, and send me the URL of yours? Thanks =)
                              – Frank Nocke
                              Oct 3 at 18:16




                              Can you fork my codepen (top-right, easy), correct & add tests, and send me the URL of yours? Thanks =)
                              – Frank Nocke
                              Oct 3 at 18:16












                              Check this
                              – germain
                              Oct 4 at 5:01




                              Check this
                              – germain
                              Oct 4 at 5:01










                              up vote
                              8
                              down vote













                              I tried a recursive approach:



                              function objHasKeys(obj, keys) {
                              var next = keys.shift();
                              return obj[next] && (! keys.length || objHasKeys(obj[next], keys));
                              }


                              The ! keys.length || kicks out of the recursion so it doesn't run the function with no keys left to test. Tests:



                              obj = {
                              path: {
                              to: {
                              the: {
                              goodKey: "hello"
                              }
                              }
                              }
                              }

                              console.log(objHasKeys(obj, ['path', 'to', 'the', 'goodKey'])); // true
                              console.log(objHasKeys(obj, ['path', 'to', 'the', 'badKey'])); // undefined


                              I am using it to print a friendly html view of a bunch of objects with unknown key/values, e.g.:



                              var biosName = objHasKeys(myObj, 'MachineInfo:BiosInfo:Name'.split(':'))
                              ? myObj.MachineInfo.BiosInfo.Name
                              : 'unknown';





                              share|improve this answer

























                                up vote
                                8
                                down vote













                                I tried a recursive approach:



                                function objHasKeys(obj, keys) {
                                var next = keys.shift();
                                return obj[next] && (! keys.length || objHasKeys(obj[next], keys));
                                }


                                The ! keys.length || kicks out of the recursion so it doesn't run the function with no keys left to test. Tests:



                                obj = {
                                path: {
                                to: {
                                the: {
                                goodKey: "hello"
                                }
                                }
                                }
                                }

                                console.log(objHasKeys(obj, ['path', 'to', 'the', 'goodKey'])); // true
                                console.log(objHasKeys(obj, ['path', 'to', 'the', 'badKey'])); // undefined


                                I am using it to print a friendly html view of a bunch of objects with unknown key/values, e.g.:



                                var biosName = objHasKeys(myObj, 'MachineInfo:BiosInfo:Name'.split(':'))
                                ? myObj.MachineInfo.BiosInfo.Name
                                : 'unknown';





                                share|improve this answer























                                  up vote
                                  8
                                  down vote










                                  up vote
                                  8
                                  down vote









                                  I tried a recursive approach:



                                  function objHasKeys(obj, keys) {
                                  var next = keys.shift();
                                  return obj[next] && (! keys.length || objHasKeys(obj[next], keys));
                                  }


                                  The ! keys.length || kicks out of the recursion so it doesn't run the function with no keys left to test. Tests:



                                  obj = {
                                  path: {
                                  to: {
                                  the: {
                                  goodKey: "hello"
                                  }
                                  }
                                  }
                                  }

                                  console.log(objHasKeys(obj, ['path', 'to', 'the', 'goodKey'])); // true
                                  console.log(objHasKeys(obj, ['path', 'to', 'the', 'badKey'])); // undefined


                                  I am using it to print a friendly html view of a bunch of objects with unknown key/values, e.g.:



                                  var biosName = objHasKeys(myObj, 'MachineInfo:BiosInfo:Name'.split(':'))
                                  ? myObj.MachineInfo.BiosInfo.Name
                                  : 'unknown';





                                  share|improve this answer












                                  I tried a recursive approach:



                                  function objHasKeys(obj, keys) {
                                  var next = keys.shift();
                                  return obj[next] && (! keys.length || objHasKeys(obj[next], keys));
                                  }


                                  The ! keys.length || kicks out of the recursion so it doesn't run the function with no keys left to test. Tests:



                                  obj = {
                                  path: {
                                  to: {
                                  the: {
                                  goodKey: "hello"
                                  }
                                  }
                                  }
                                  }

                                  console.log(objHasKeys(obj, ['path', 'to', 'the', 'goodKey'])); // true
                                  console.log(objHasKeys(obj, ['path', 'to', 'the', 'badKey'])); // undefined


                                  I am using it to print a friendly html view of a bunch of objects with unknown key/values, e.g.:



                                  var biosName = objHasKeys(myObj, 'MachineInfo:BiosInfo:Name'.split(':'))
                                  ? myObj.MachineInfo.BiosInfo.Name
                                  : 'unknown';






                                  share|improve this answer












                                  share|improve this answer



                                  share|improve this answer










                                  answered Nov 7 '13 at 23:00









                                  jrode

                                  32137




                                  32137






















                                      up vote
                                      6
                                      down vote













                                      You can also use tc39 optional chaining proposal together with babel 7 - tc39-proposal-optional-chaining



                                      Code would look like this:



                                        const test = test?.level1?.level2?.level3;
                                      if (test) alert(test);





                                      share|improve this answer





















                                      • Note that this syntax will almost certainly change, as some TC39 members have objections.
                                        – jhpratt
                                        Sep 24 at 1:59










                                      • Probably but this will be available in some form in time, and that's the only thing that matters .. It's one of the features I miss the most in JS.
                                        – Goran.it
                                        Sep 24 at 7:00















                                      up vote
                                      6
                                      down vote













                                      You can also use tc39 optional chaining proposal together with babel 7 - tc39-proposal-optional-chaining



                                      Code would look like this:



                                        const test = test?.level1?.level2?.level3;
                                      if (test) alert(test);





                                      share|improve this answer





















                                      • Note that this syntax will almost certainly change, as some TC39 members have objections.
                                        – jhpratt
                                        Sep 24 at 1:59










                                      • Probably but this will be available in some form in time, and that's the only thing that matters .. It's one of the features I miss the most in JS.
                                        – Goran.it
                                        Sep 24 at 7:00













                                      up vote
                                      6
                                      down vote










                                      up vote
                                      6
                                      down vote









                                      You can also use tc39 optional chaining proposal together with babel 7 - tc39-proposal-optional-chaining



                                      Code would look like this:



                                        const test = test?.level1?.level2?.level3;
                                      if (test) alert(test);





                                      share|improve this answer












                                      You can also use tc39 optional chaining proposal together with babel 7 - tc39-proposal-optional-chaining



                                      Code would look like this:



                                        const test = test?.level1?.level2?.level3;
                                      if (test) alert(test);






                                      share|improve this answer












                                      share|improve this answer



                                      share|improve this answer










                                      answered Jun 14 at 7:59









                                      Goran.it

                                      3,20711620




                                      3,20711620












                                      • Note that this syntax will almost certainly change, as some TC39 members have objections.
                                        – jhpratt
                                        Sep 24 at 1:59










                                      • Probably but this will be available in some form in time, and that's the only thing that matters .. It's one of the features I miss the most in JS.
                                        – Goran.it
                                        Sep 24 at 7:00


















                                      • Note that this syntax will almost certainly change, as some TC39 members have objections.
                                        – jhpratt
                                        Sep 24 at 1:59










                                      • Probably but this will be available in some form in time, and that's the only thing that matters .. It's one of the features I miss the most in JS.
                                        – Goran.it
                                        Sep 24 at 7:00
















                                      Note that this syntax will almost certainly change, as some TC39 members have objections.
                                      – jhpratt
                                      Sep 24 at 1:59




                                      Note that this syntax will almost certainly change, as some TC39 members have objections.
                                      – jhpratt
                                      Sep 24 at 1:59












                                      Probably but this will be available in some form in time, and that's the only thing that matters .. It's one of the features I miss the most in JS.
                                      – Goran.it
                                      Sep 24 at 7:00




                                      Probably but this will be available in some form in time, and that's the only thing that matters .. It's one of the features I miss the most in JS.
                                      – Goran.it
                                      Sep 24 at 7:00










                                      up vote
                                      5
                                      down vote













                                      I think the following script gives more readable representation.



                                      declare a function:



                                      var o = function(obj) { return obj || {};};


                                      then use it like this:



                                      if (o(o(o(o(test).level1).level2).level3)
                                      {

                                      }


                                      I call it "sad clown technique" because it is using sign o(





                                      EDIT:



                                      here is a version for TypeScript



                                      it gives type checks at compile time (as well as the intellisense if you use a tool like Visual Studio)



                                      export function o<T>(someObject: T, defaultValue: T = {} as T) : T {
                                      if (typeof someObject === 'undefined' || someObject === null)
                                      return defaultValue;
                                      else
                                      return someObject;
                                      }


                                      the usage is the same:



                                      o(o(o(o(test).level1).level2).level3


                                      but this time intellisense works!



                                      plus, you can set a default value:



                                      o(o(o(o(o(test).level1).level2).level3, "none")





                                      share|improve this answer























                                      • °0o <°(())))><
                                        – DanFromGermany
                                        Nov 17 '16 at 14:23















                                      up vote
                                      5
                                      down vote













                                      I think the following script gives more readable representation.



                                      declare a function:



                                      var o = function(obj) { return obj || {};};


                                      then use it like this:



                                      if (o(o(o(o(test).level1).level2).level3)
                                      {

                                      }


                                      I call it "sad clown technique" because it is using sign o(





                                      EDIT:



                                      here is a version for TypeScript



                                      it gives type checks at compile time (as well as the intellisense if you use a tool like Visual Studio)



                                      export function o<T>(someObject: T, defaultValue: T = {} as T) : T {
                                      if (typeof someObject === 'undefined' || someObject === null)
                                      return defaultValue;
                                      else
                                      return someObject;
                                      }


                                      the usage is the same:



                                      o(o(o(o(test).level1).level2).level3


                                      but this time intellisense works!



                                      plus, you can set a default value:



                                      o(o(o(o(o(test).level1).level2).level3, "none")





                                      share|improve this answer























                                      • °0o <°(())))><
                                        – DanFromGermany
                                        Nov 17 '16 at 14:23













                                      up vote
                                      5
                                      down vote










                                      up vote
                                      5
                                      down vote









                                      I think the following script gives more readable representation.



                                      declare a function:



                                      var o = function(obj) { return obj || {};};


                                      then use it like this:



                                      if (o(o(o(o(test).level1).level2).level3)
                                      {

                                      }


                                      I call it "sad clown technique" because it is using sign o(





                                      EDIT:



                                      here is a version for TypeScript



                                      it gives type checks at compile time (as well as the intellisense if you use a tool like Visual Studio)



                                      export function o<T>(someObject: T, defaultValue: T = {} as T) : T {
                                      if (typeof someObject === 'undefined' || someObject === null)
                                      return defaultValue;
                                      else
                                      return someObject;
                                      }


                                      the usage is the same:



                                      o(o(o(o(test).level1).level2).level3


                                      but this time intellisense works!



                                      plus, you can set a default value:



                                      o(o(o(o(o(test).level1).level2).level3, "none")





                                      share|improve this answer














                                      I think the following script gives more readable representation.



                                      declare a function:



                                      var o = function(obj) { return obj || {};};


                                      then use it like this:



                                      if (o(o(o(o(test).level1).level2).level3)
                                      {

                                      }


                                      I call it "sad clown technique" because it is using sign o(





                                      EDIT:



                                      here is a version for TypeScript



                                      it gives type checks at compile time (as well as the intellisense if you use a tool like Visual Studio)



                                      export function o<T>(someObject: T, defaultValue: T = {} as T) : T {
                                      if (typeof someObject === 'undefined' || someObject === null)
                                      return defaultValue;
                                      else
                                      return someObject;
                                      }


                                      the usage is the same:



                                      o(o(o(o(test).level1).level2).level3


                                      but this time intellisense works!



                                      plus, you can set a default value:



                                      o(o(o(o(o(test).level1).level2).level3, "none")






                                      share|improve this answer














                                      share|improve this answer



                                      share|improve this answer








                                      edited Jan 13 '17 at 0:16

























                                      answered Feb 3 '16 at 5:45









                                      VeganHunter

                                      1,510199




                                      1,510199












                                      • °0o <°(())))><
                                        – DanFromGermany
                                        Nov 17 '16 at 14:23


















                                      • °0o <°(())))><
                                        – DanFromGermany
                                        Nov 17 '16 at 14:23
















                                      °0o <°(())))><
                                      – DanFromGermany
                                      Nov 17 '16 at 14:23




                                      °0o <°(())))><
                                      – DanFromGermany
                                      Nov 17 '16 at 14:23










                                      up vote
                                      5
                                      down vote













                                      I didn't see any example of someone using Proxies



                                      So I came up with my own.
                                      The great thing about it is that you don't have to interpolate strings. You can actually return a chain-able object function and do some magical things with it. You can even call functions and get array indexes to check for deep objects






                                      function resolve(target) {
                                      var noop = () => {} // We us a noop function so we can call methods also
                                      return new Proxy(noop, {
                                      get(noop, key) {
                                      // return end result if key is _result
                                      return key === '_result'
                                      ? target
                                      : resolve( // resolve with target value or undefined
                                      target === undefined ? undefined : target[key]
                                      )
                                      },

                                      // if we want to test a function then we can do so alos thanks to using noop
                                      // instead of using target in our proxy
                                      apply(noop, that, args) {
                                      return resolve(typeof target === 'function' ? target.apply(that, args) : undefined)
                                      },
                                      })
                                      }

                                      // some modified examples from the accepted answer
                                      var test = {level1: {level2:() => ({level3:'level3'})}}
                                      var test1 = {key1: {key2: ['item0']}}

                                      // You need to get _result in the end to get the final result

                                      console.log(resolve(test).level1.level2().level3._result)
                                      console.log(resolve(test).level1.level2().level3.level4.level5._result)
                                      console.log(resolve(test1).key1.key2[0]._result)
                                      console.log(resolve(test1)[0].key._result) // don't exist





                                      The above code works fine for synchronous stuff. But how would you test something that is asynchronous like this ajax call?
                                      How do you test that? what if the response isn't json when it returns a 500 http error?



                                      window.fetch('https://httpbin.org/get')
                                      .then(function(response) {
                                      return response.json()
                                      })
                                      .then(function(json) {
                                      console.log(json.headers['User-Agent'])
                                      })


                                      sure you could use async/await to get rid of some callbacks. But what if you could do it even more magically? something that looks like this:



                                      fetch('https://httpbin.org/get').json().headers['User-Agent']


                                      You probably wonder where all the promise & .then chains are... this could be blocking for all that you know... but using the same Proxy technique with promise you can actually test deeply nested complex path for it existence without ever writing a single function






                                      function resolve(target) { 
                                      return new Proxy(() => {}, {
                                      get(noop, key) {
                                      return key === 'then' ? target.then.bind(target) : resolve(
                                      Promise.resolve(target).then(target => {
                                      if (typeof target[key] === 'function') return target[key].bind(target)
                                      return target[key]
                                      })
                                      )
                                      },

                                      apply(noop, that, args) {
                                      return resolve(target.then(result => {
                                      return result.apply(that, args)
                                      }))
                                      },
                                      })
                                      }

                                      // this feels very much synchronous but are still non blocking :)
                                      resolve(window) // this will chain a noop function until you call then()
                                      .fetch('https://httpbin.org/get')
                                      .json()
                                      .headers['User-Agent']
                                      .then(console.log, console.warn) // you get a warning if it doesn't exist

                                      // You could use this method also for the first test object
                                      // also, but it would have to call .then() in the end



                                      // Another example
                                      resolve(window)
                                      .fetch('https://httpbin.org/get?items=4&items=2')
                                      .json()
                                      .args
                                      .items
                                      // nice that you can map an array item without even having it ready
                                      .map(n => ~~n * 4)
                                      .then(console.log, console.warn) // you get a warning if it doesn't exist








                                      share|improve this answer























                                      • If someone is interested, I've publish the async version on npm
                                        – Endless
                                        Sep 4 '17 at 12:09

















                                      up vote
                                      5
                                      down vote













                                      I didn't see any example of someone using Proxies



                                      So I came up with my own.
                                      The great thing about it is that you don't have to interpolate strings. You can actually return a chain-able object function and do some magical things with it. You can even call functions and get array indexes to check for deep objects






                                      function resolve(target) {
                                      var noop = () => {} // We us a noop function so we can call methods also
                                      return new Proxy(noop, {
                                      get(noop, key) {
                                      // return end result if key is _result
                                      return key === '_result'
                                      ? target
                                      : resolve( // resolve with target value or undefined
                                      target === undefined ? undefined : target[key]
                                      )
                                      },

                                      // if we want to test a function then we can do so alos thanks to using noop
                                      // instead of using target in our proxy
                                      apply(noop, that, args) {
                                      return resolve(typeof target === 'function' ? target.apply(that, args) : undefined)
                                      },
                                      })
                                      }

                                      // some modified examples from the accepted answer
                                      var test = {level1: {level2:() => ({level3:'level3'})}}
                                      var test1 = {key1: {key2: ['item0']}}

                                      // You need to get _result in the end to get the final result

                                      console.log(resolve(test).level1.level2().level3._result)
                                      console.log(resolve(test).level1.level2().level3.level4.level5._result)
                                      console.log(resolve(test1).key1.key2[0]._result)
                                      console.log(resolve(test1)[0].key._result) // don't exist





                                      The above code works fine for synchronous stuff. But how would you test something that is asynchronous like this ajax call?
                                      How do you test that? what if the response isn't json when it returns a 500 http error?



                                      window.fetch('https://httpbin.org/get')
                                      .then(function(response) {
                                      return response.json()
                                      })
                                      .then(function(json) {
                                      console.log(json.headers['User-Agent'])
                                      })


                                      sure you could use async/await to get rid of some callbacks. But what if you could do it even more magically? something that looks like this:



                                      fetch('https://httpbin.org/get').json().headers['User-Agent']


                                      You probably wonder where all the promise & .then chains are... this could be blocking for all that you know... but using the same Proxy technique with promise you can actually test deeply nested complex path for it existence without ever writing a single function






                                      function resolve(target) { 
                                      return new Proxy(() => {}, {
                                      get(noop, key) {
                                      return key === 'then' ? target.then.bind(target) : resolve(
                                      Promise.resolve(target).then(target => {
                                      if (typeof target[key] === 'function') return target[key].bind(target)
                                      return target[key]
                                      })
                                      )
                                      },

                                      apply(noop, that, args) {
                                      return resolve(target.then(result => {
                                      return result.apply(that, args)
                                      }))
                                      },
                                      })
                                      }

                                      // this feels very much synchronous but are still non blocking :)
                                      resolve(window) // this will chain a noop function until you call then()
                                      .fetch('https://httpbin.org/get')
                                      .json()
                                      .headers['User-Agent']
                                      .then(console.log, console.warn) // you get a warning if it doesn't exist

                                      // You could use this method also for the first test object
                                      // also, but it would have to call .then() in the end



                                      // Another example
                                      resolve(window)
                                      .fetch('https://httpbin.org/get?items=4&items=2')
                                      .json()
                                      .args
                                      .items
                                      // nice that you can map an array item without even having it ready
                                      .map(n => ~~n * 4)
                                      .then(console.log, console.warn) // you get a warning if it doesn't exist








                                      share|improve this answer























                                      • If someone is interested, I've publish the async version on npm
                                        – Endless
                                        Sep 4 '17 at 12:09















                                      up vote
                                      5
                                      down vote










                                      up vote
                                      5
                                      down vote









                                      I didn't see any example of someone using Proxies



                                      So I came up with my own.
                                      The great thing about it is that you don't have to interpolate strings. You can actually return a chain-able object function and do some magical things with it. You can even call functions and get array indexes to check for deep objects






                                      function resolve(target) {
                                      var noop = () => {} // We us a noop function so we can call methods also
                                      return new Proxy(noop, {
                                      get(noop, key) {
                                      // return end result if key is _result
                                      return key === '_result'
                                      ? target
                                      : resolve( // resolve with target value or undefined
                                      target === undefined ? undefined : target[key]
                                      )
                                      },

                                      // if we want to test a function then we can do so alos thanks to using noop
                                      // instead of using target in our proxy
                                      apply(noop, that, args) {
                                      return resolve(typeof target === 'function' ? target.apply(that, args) : undefined)
                                      },
                                      })
                                      }

                                      // some modified examples from the accepted answer
                                      var test = {level1: {level2:() => ({level3:'level3'})}}
                                      var test1 = {key1: {key2: ['item0']}}

                                      // You need to get _result in the end to get the final result

                                      console.log(resolve(test).level1.level2().level3._result)
                                      console.log(resolve(test).level1.level2().level3.level4.level5._result)
                                      console.log(resolve(test1).key1.key2[0]._result)
                                      console.log(resolve(test1)[0].key._result) // don't exist





                                      The above code works fine for synchronous stuff. But how would you test something that is asynchronous like this ajax call?
                                      How do you test that? what if the response isn't json when it returns a 500 http error?



                                      window.fetch('https://httpbin.org/get')
                                      .then(function(response) {
                                      return response.json()
                                      })
                                      .then(function(json) {
                                      console.log(json.headers['User-Agent'])
                                      })


                                      sure you could use async/await to get rid of some callbacks. But what if you could do it even more magically? something that looks like this:



                                      fetch('https://httpbin.org/get').json().headers['User-Agent']


                                      You probably wonder where all the promise & .then chains are... this could be blocking for all that you know... but using the same Proxy technique with promise you can actually test deeply nested complex path for it existence without ever writing a single function






                                      function resolve(target) { 
                                      return new Proxy(() => {}, {
                                      get(noop, key) {
                                      return key === 'then' ? target.then.bind(target) : resolve(
                                      Promise.resolve(target).then(target => {
                                      if (typeof target[key] === 'function') return target[key].bind(target)
                                      return target[key]
                                      })
                                      )
                                      },

                                      apply(noop, that, args) {
                                      return resolve(target.then(result => {
                                      return result.apply(that, args)
                                      }))
                                      },
                                      })
                                      }

                                      // this feels very much synchronous but are still non blocking :)
                                      resolve(window) // this will chain a noop function until you call then()
                                      .fetch('https://httpbin.org/get')
                                      .json()
                                      .headers['User-Agent']
                                      .then(console.log, console.warn) // you get a warning if it doesn't exist

                                      // You could use this method also for the first test object
                                      // also, but it would have to call .then() in the end



                                      // Another example
                                      resolve(window)
                                      .fetch('https://httpbin.org/get?items=4&items=2')
                                      .json()
                                      .args
                                      .items
                                      // nice that you can map an array item without even having it ready
                                      .map(n => ~~n * 4)
                                      .then(console.log, console.warn) // you get a warning if it doesn't exist








                                      share|improve this answer














                                      I didn't see any example of someone using Proxies



                                      So I came up with my own.
                                      The great thing about it is that you don't have to interpolate strings. You can actually return a chain-able object function and do some magical things with it. You can even call functions and get array indexes to check for deep objects






                                      function resolve(target) {
                                      var noop = () => {} // We us a noop function so we can call methods also
                                      return new Proxy(noop, {
                                      get(noop, key) {
                                      // return end result if key is _result
                                      return key === '_result'
                                      ? target
                                      : resolve( // resolve with target value or undefined
                                      target === undefined ? undefined : target[key]
                                      )
                                      },

                                      // if we want to test a function then we can do so alos thanks to using noop
                                      // instead of using target in our proxy
                                      apply(noop, that, args) {
                                      return resolve(typeof target === 'function' ? target.apply(that, args) : undefined)
                                      },
                                      })
                                      }

                                      // some modified examples from the accepted answer
                                      var test = {level1: {level2:() => ({level3:'level3'})}}
                                      var test1 = {key1: {key2: ['item0']}}

                                      // You need to get _result in the end to get the final result

                                      console.log(resolve(test).level1.level2().level3._result)
                                      console.log(resolve(test).level1.level2().level3.level4.level5._result)
                                      console.log(resolve(test1).key1.key2[0]._result)
                                      console.log(resolve(test1)[0].key._result) // don't exist





                                      The above code works fine for synchronous stuff. But how would you test something that is asynchronous like this ajax call?
                                      How do you test that? what if the response isn't json when it returns a 500 http error?



                                      window.fetch('https://httpbin.org/get')
                                      .then(function(response) {
                                      return response.json()
                                      })
                                      .then(function(json) {
                                      console.log(json.headers['User-Agent'])
                                      })


                                      sure you could use async/await to get rid of some callbacks. But what if you could do it even more magically? something that looks like this:



                                      fetch('https://httpbin.org/get').json().headers['User-Agent']


                                      You probably wonder where all the promise & .then chains are... this could be blocking for all that you know... but using the same Proxy technique with promise you can actually test deeply nested complex path for it existence without ever writing a single function






                                      function resolve(target) { 
                                      return new Proxy(() => {}, {
                                      get(noop, key) {
                                      return key === 'then' ? target.then.bind(target) : resolve(
                                      Promise.resolve(target).then(target => {
                                      if (typeof target[key] === 'function') return target[key].bind(target)
                                      return target[key]
                                      })
                                      )
                                      },

                                      apply(noop, that, args) {
                                      return resolve(target.then(result => {
                                      return result.apply(that, args)
                                      }))
                                      },
                                      })
                                      }

                                      // this feels very much synchronous but are still non blocking :)
                                      resolve(window) // this will chain a noop function until you call then()
                                      .fetch('https://httpbin.org/get')
                                      .json()
                                      .headers['User-Agent']
                                      .then(console.log, console.warn) // you get a warning if it doesn't exist

                                      // You could use this method also for the first test object
                                      // also, but it would have to call .then() in the end



                                      // Another example
                                      resolve(window)
                                      .fetch('https://httpbin.org/get?items=4&items=2')
                                      .json()
                                      .args
                                      .items
                                      // nice that you can map an array item without even having it ready
                                      .map(n => ~~n * 4)
                                      .then(console.log, console.warn) // you get a warning if it doesn't exist








                                      function resolve(target) {
                                      var noop = () => {} // We us a noop function so we can call methods also
                                      return new Proxy(noop, {
                                      get(noop, key) {
                                      // return end result if key is _result
                                      return key === '_result'
                                      ? target
                                      : resolve( // resolve with target value or undefined
                                      target === undefined ? undefined : target[key]
                                      )
                                      },

                                      // if we want to test a function then we can do so alos thanks to using noop
                                      // instead of using target in our proxy
                                      apply(noop, that, args) {
                                      return resolve(typeof target === 'function' ? target.apply(that, args) : undefined)
                                      },
                                      })
                                      }

                                      // some modified examples from the accepted answer
                                      var test = {level1: {level2:() => ({level3:'level3'})}}
                                      var test1 = {key1: {key2: ['item0']}}

                                      // You need to get _result in the end to get the final result

                                      console.log(resolve(test).level1.level2().level3._result)
                                      console.log(resolve(test).level1.level2().level3.level4.level5._result)
                                      console.log(resolve(test1).key1.key2[0]._result)
                                      console.log(resolve(test1)[0].key._result) // don't exist





                                      function resolve(target) {
                                      var noop = () => {} // We us a noop function so we can call methods also
                                      return new Proxy(noop, {
                                      get(noop, key) {
                                      // return end result if key is _result
                                      return key === '_result'
                                      ? target
                                      : resolve( // resolve with target value or undefined
                                      target === undefined ? undefined : target[key]
                                      )
                                      },

                                      // if we want to test a function then we can do so alos thanks to using noop
                                      // instead of using target in our proxy
                                      apply(noop, that, args) {
                                      return resolve(typeof target === 'function' ? target.apply(that, args) : undefined)
                                      },
                                      })
                                      }

                                      // some modified examples from the accepted answer
                                      var test = {level1: {level2:() => ({level3:'level3'})}}
                                      var test1 = {key1: {key2: ['item0']}}

                                      // You need to get _result in the end to get the final result

                                      console.log(resolve(test).level1.level2().level3._result)
                                      console.log(resolve(test).level1.level2().level3.level4.level5._result)
                                      console.log(resolve(test1).key1.key2[0]._result)
                                      console.log(resolve(test1)[0].key._result) // don't exist





                                      function resolve(target) { 
                                      return new Proxy(() => {}, {
                                      get(noop, key) {
                                      return key === 'then' ? target.then.bind(target) : resolve(
                                      Promise.resolve(target).then(target => {
                                      if (typeof target[key] === 'function') return target[key].bind(target)
                                      return target[key]
                                      })
                                      )
                                      },

                                      apply(noop, that, args) {
                                      return resolve(target.then(result => {
                                      return result.apply(that, args)
                                      }))
                                      },
                                      })
                                      }

                                      // this feels very much synchronous but are still non blocking :)
                                      resolve(window) // this will chain a noop function until you call then()
                                      .fetch('https://httpbin.org/get')
                                      .json()
                                      .headers['User-Agent']
                                      .then(console.log, console.warn) // you get a warning if it doesn't exist

                                      // You could use this method also for the first test object
                                      // also, but it would have to call .then() in the end



                                      // Another example
                                      resolve(window)
                                      .fetch('https://httpbin.org/get?items=4&items=2')
                                      .json()
                                      .args
                                      .items
                                      // nice that you can map an array item without even having it ready
                                      .map(n => ~~n * 4)
                                      .then(console.log, console.warn) // you get a warning if it doesn't exist





                                      function resolve(target) { 
                                      return new Proxy(() => {}, {
                                      get(noop, key) {
                                      return key === 'then' ? target.then.bind(target) : resolve(
                                      Promise.resolve(target).then(target => {
                                      if (typeof target[key] === 'function') return target[key].bind(target)
                                      return target[key]
                                      })
                                      )
                                      },

                                      apply(noop, that, args) {
                                      return resolve(target.then(result => {
                                      return result.apply(that, args)
                                      }))
                                      },
                                      })
                                      }

                                      // this feels very much synchronous but are still non blocking :)
                                      resolve(window) // this will chain a noop function until you call then()
                                      .fetch('https://httpbin.org/get')
                                      .json()
                                      .headers['User-Agent']
                                      .then(console.log, console.warn) // you get a warning if it doesn't exist

                                      // You could use this method also for the first test object
                                      // also, but it would have to call .then() in the end



                                      // Another example
                                      resolve(window)
                                      .fetch('https://httpbin.org/get?items=4&items=2')
                                      .json()
                                      .args
                                      .items
                                      // nice that you can map an array item without even having it ready
                                      .map(n => ~~n * 4)
                                      .then(console.log, console.warn) // you get a warning if it doesn't exist






                                      share|improve this answer














                                      share|improve this answer



                                      share|improve this answer








                                      edited Jul 27 at 14:55









                                      Michiel

                                      2,67622237




                                      2,67622237










                                      answered May 18 '17 at 12:50









                                      Endless

                                      11.8k64968




                                      11.8k64968












                                      • If someone is interested, I've publish the async version on npm
                                        – Endless
                                        Sep 4 '17 at 12:09




















                                      • If someone is interested, I've publish the async version on npm
                                        – Endless
                                        Sep 4 '17 at 12:09


















                                      If someone is interested, I've publish the async version on npm
                                      – Endless
                                      Sep 4 '17 at 12:09






                                      If someone is interested, I've publish the async version on npm
                                      – Endless
                                      Sep 4 '17 at 12:09












                                      up vote
                                      4
                                      down vote













                                      One simple way is this:



                                      try {
                                      alert(test.level1.level2.level3);
                                      } catch(e) {
                                      alert("undefined"); // this is optional to put any output here
                                      }


                                      The try/catch catches the cases for when any of the higher level objects such as test, test.level1, test.level1.level2 are not defined.






                                      share|improve this answer

























                                        up vote
                                        4
                                        down vote













                                        One simple way is this:



                                        try {
                                        alert(test.level1.level2.level3);
                                        } catch(e) {
                                        alert("undefined"); // this is optional to put any output here
                                        }


                                        The try/catch catches the cases for when any of the higher level objects such as test, test.level1, test.level1.level2 are not defined.






                                        share|improve this answer























                                          up vote
                                          4
                                          down vote










                                          up vote
                                          4
                                          down vote









                                          One simple way is this:



                                          try {
                                          alert(test.level1.level2.level3);
                                          } catch(e) {
                                          alert("undefined"); // this is optional to put any output here
                                          }


                                          The try/catch catches the cases for when any of the higher level objects such as test, test.level1, test.level1.level2 are not defined.






                                          share|improve this answer












                                          One simple way is this:



                                          try {
                                          alert(test.level1.level2.level3);
                                          } catch(e) {
                                          alert("undefined"); // this is optional to put any output here
                                          }


                                          The try/catch catches the cases for when any of the higher level objects such as test, test.level1, test.level1.level2 are not defined.







                                          share|improve this answer












                                          share|improve this answer



                                          share|improve this answer










                                          answered Oct 12 '11 at 15:48









                                          jfriend00

                                          426k51545591




                                          426k51545591






















                                              up vote
                                              3
                                              down vote













                                              A shorter, ES5 version of @CMS's excellent answer:



                                              // Check the obj has the keys in the order mentioned. Used for checking JSON results.  
                                              var checkObjHasKeys = function(obj, keys) {
                                              var success = true;
                                              keys.forEach( function(key) {
                                              if ( ! obj.hasOwnProperty(key)) {
                                              success = false;
                                              }
                                              obj = obj[key];
                                              })
                                              return success;
                                              }


                                              With a similar test:



                                              var test = { level1:{level2:{level3:'result'}}};
                                              utils.checkObjHasKeys(test, ['level1', 'level2', 'level3']); // true
                                              utils.checkObjHasKeys(test, ['level1', 'level2', 'foo']); // false





                                              share|improve this answer





















                                              • the only issue with this is if there are multiple levels of undefined keys, then you get a TypeError, e.g. checkObjHasKeys(test, ['level1', 'level2', 'asdf', 'asdf']);
                                                – JKS
                                                Jul 19 '12 at 17:34






                                              • 1




                                                A more suitable method is every, whose value can be returned directly.
                                                – RobG
                                                Aug 12 '15 at 11:59










                                              • Maybe change success = false; to return false. You should bail out once you know it breaks, nothing deeper can exist once it's null or undefined. This would prevent the errors on the deeper nested items, since they obviously don't exist either.
                                                – Wade
                                                Nov 4 '16 at 20:16















                                              up vote
                                              3
                                              down vote













                                              A shorter, ES5 version of @CMS's excellent answer:



                                              // Check the obj has the keys in the order mentioned. Used for checking JSON results.  
                                              var checkObjHasKeys = function(obj, keys) {
                                              var success = true;
                                              keys.forEach( function(key) {
                                              if ( ! obj.hasOwnProperty(key)) {
                                              success = false;
                                              }
                                              obj = obj[key];
                                              })
                                              return success;
                                              }


                                              With a similar test:



                                              var test = { level1:{level2:{level3:'result'}}};
                                              utils.checkObjHasKeys(test, ['level1', 'level2', 'level3']); // true
                                              utils.checkObjHasKeys(test, ['level1', 'level2', 'foo']); // false





                                              share|improve this answer





















                                              • the only issue with this is if there are multiple levels of undefined keys, then you get a TypeError, e.g. checkObjHasKeys(test, ['level1', 'level2', 'asdf', 'asdf']);
                                                – JKS
                                                Jul 19 '12 at 17:34






                                              • 1




                                                A more suitable method is every, whose value can be returned directly.
                                                – RobG
                                                Aug 12 '15 at 11:59










                                              • Maybe change success = false; to return false. You should bail out once you know it breaks, nothing deeper can exist once it's null or undefined. This would prevent the errors on the deeper nested items, since they obviously don't exist either.
                                                – Wade
                                                Nov 4 '16 at 20:16













                                              up vote
                                              3
                                              down vote










                                              up vote
                                              3
                                              down vote









                                              A shorter, ES5 version of @CMS's excellent answer:



                                              // Check the obj has the keys in the order mentioned. Used for checking JSON results.  
                                              var checkObjHasKeys = function(obj, keys) {
                                              var success = true;
                                              keys.forEach( function(key) {
                                              if ( ! obj.hasOwnProperty(key)) {
                                              success = false;
                                              }
                                              obj = obj[key];
                                              })
                                              return success;
                                              }


                                              With a similar test:



                                              var test = { level1:{level2:{level3:'result'}}};
                                              utils.checkObjHasKeys(test, ['level1', 'level2', 'level3']); // true
                                              utils.checkObjHasKeys(test, ['level1', 'level2', 'foo']); // false





                                              share|improve this answer












                                              A shorter, ES5 version of @CMS's excellent answer:



                                              // Check the obj has the keys in the order mentioned. Used for checking JSON results.  
                                              var checkObjHasKeys = function(obj, keys) {
                                              var success = true;
                                              keys.forEach( function(key) {
                                              if ( ! obj.hasOwnProperty(key)) {
                                              success = false;
                                              }
                                              obj = obj[key];
                                              })
                                              return success;
                                              }


                                              With a similar test:



                                              var test = { level1:{level2:{level3:'result'}}};
                                              utils.checkObjHasKeys(test, ['level1', 'level2', 'level3']); // true
                                              utils.checkObjHasKeys(test, ['level1', 'level2', 'foo']); // false






                                              share|improve this answer












                                              share|improve this answer



                                              share|improve this answer










                                              answered May 21 '12 at 9:28









                                              mikemaccana

                                              41.5k44228292




                                              41.5k44228292












                                              • the only issue with this is if there are multiple levels of undefined keys, then you get a TypeError, e.g. checkObjHasKeys(test, ['level1', 'level2', 'asdf', 'asdf']);
                                                – JKS
                                                Jul 19 '12 at 17:34






                                              • 1




                                                A more suitable method is every, whose value can be returned directly.
                                                – RobG
                                                Aug 12 '15 at 11:59










                                              • Maybe change success = false; to return false. You should bail out once you know it breaks, nothing deeper can exist once it's null or undefined. This would prevent the errors on the deeper nested items, since they obviously don't exist either.
                                                – Wade
                                                Nov 4 '16 at 20:16


















                                              • the only issue with this is if there are multiple levels of undefined keys, then you get a TypeError, e.g. checkObjHasKeys(test, ['level1', 'level2', 'asdf', 'asdf']);
                                                – JKS
                                                Jul 19 '12 at 17:34






                                              • 1




                                                A more suitable method is every, whose value can be returned directly.
                                                – RobG
                                                Aug 12 '15 at 11:59










                                              • Maybe change success = false; to return false. You should bail out once you know it breaks, nothing deeper can exist once it's null or undefined. This would prevent the errors on the deeper nested items, since they obviously don't exist either.
                                                – Wade
                                                Nov 4 '16 at 20:16
















                                              the only issue with this is if there are multiple levels of undefined keys, then you get a TypeError, e.g. checkObjHasKeys(test, ['level1', 'level2', 'asdf', 'asdf']);
                                              – JKS
                                              Jul 19 '12 at 17:34




                                              the only issue with this is if there are multiple levels of undefined keys, then you get a TypeError, e.g. checkObjHasKeys(test, ['level1', 'level2', 'asdf', 'asdf']);
                                              – JKS
                                              Jul 19 '12 at 17:34




                                              1




                                              1




                                              A more suitable method is every, whose value can be returned directly.
                                              – RobG
                                              Aug 12 '15 at 11:59




                                              A more suitable method is every, whose value can be returned directly.
                                              – RobG
                                              Aug 12 '15 at 11:59












                                              Maybe change success = false; to return false. You should bail out once you know it breaks, nothing deeper can exist once it's null or undefined. This would prevent the errors on the deeper nested items, since they obviously don't exist either.
                                              – Wade
                                              Nov 4 '16 at 20:16




                                              Maybe change success = false; to return false. You should bail out once you know it breaks, nothing deeper can exist once it's null or undefined. This would prevent the errors on the deeper nested items, since they obviously don't exist either.
                                              – Wade
                                              Nov 4 '16 at 20:16










                                              up vote
                                              3
                                              down vote













                                              Based on this answer, I came up with this generic function using ES2015 which would solve the problem



                                              function validChain( object, ...keys ) {
                                              return keys.reduce( ( a, b ) => ( a || { } )[ b ], object ) !== undefined;
                                              }

                                              var test = {
                                              first: {
                                              second: {
                                              third: "This is not the key your are looking for"
                                              }
                                              }
                                              }

                                              if ( validChain( test, "first", "second", "third" ) ) {
                                              console.log( test.first.second.third );
                                              }





                                              share|improve this answer



















                                              • 1




                                                Here is my final approach function validChain (object, path) { return path.split('.').reduce((a, b) => (a || { })[b], object) !== undefined }
                                                – James Harrington
                                                Nov 10 '17 at 21:45















                                              up vote
                                              3
                                              down vote













                                              Based on this answer, I came up with this generic function using ES2015 which would solve the problem



                                              function validChain( object, ...keys ) {
                                              return keys.reduce( ( a, b ) => ( a || { } )[ b ], object ) !== undefined;
                                              }

                                              var test = {
                                              first: {
                                              second: {
                                              third: "This is not the key your are looking for"
                                              }
                                              }
                                              }

                                              if ( validChain( test, "first", "second", "third" ) ) {
                                              console.log( test.first.second.third );
                                              }





                                              share|improve this answer



















                                              • 1




                                                Here is my final approach function validChain (object, path) { return path.split('.').reduce((a, b) => (a || { })[b], object) !== undefined }
                                                – James Harrington
                                                Nov 10 '17 at 21:45













                                              up vote
                                              3
                                              down vote










                                              up vote
                                              3
                                              down vote









                                              Based on this answer, I came up with this generic function using ES2015 which would solve the problem



                                              function validChain( object, ...keys ) {
                                              return keys.reduce( ( a, b ) => ( a || { } )[ b ], object ) !== undefined;
                                              }

                                              var test = {
                                              first: {
                                              second: {
                                              third: "This is not the key your are looking for"
                                              }
                                              }
                                              }

                                              if ( validChain( test, "first", "second", "third" ) ) {
                                              console.log( test.first.second.third );
                                              }





                                              share|improve this answer














                                              Based on this answer, I came up with this generic function using ES2015 which would solve the problem



                                              function validChain( object, ...keys ) {
                                              return keys.reduce( ( a, b ) => ( a || { } )[ b ], object ) !== undefined;
                                              }

                                              var test = {
                                              first: {
                                              second: {
                                              third: "This is not the key your are looking for"
                                              }
                                              }
                                              }

                                              if ( validChain( test, "first", "second", "third" ) ) {
                                              console.log( test.first.second.third );
                                              }






                                              share|improve this answer














                                              share|improve this answer



                                              share|improve this answer








                                              edited May 23 '17 at 11:47









                                              Community

                                              11




                                              11










                                              answered Aug 15 '16 at 9:11









                                              Alex Moldovan

                                              1,678812




                                              1,678812








                                              • 1




                                                Here is my final approach function validChain (object, path) { return path.split('.').reduce((a, b) => (a || { })[b], object) !== undefined }
                                                – James Harrington
                                                Nov 10 '17 at 21:45














                                              • 1




                                                Here is my final approach function validChain (object, path) { return path.split('.').reduce((a, b) => (a || { })[b], object) !== undefined }
                                                – James Harrington
                                                Nov 10 '17 at 21:45








                                              1




                                              1




                                              Here is my final approach function validChain (object, path) { return path.split('.').reduce((a, b) => (a || { })[b], object) !== undefined }
                                              – James Harrington
                                              Nov 10 '17 at 21:45




                                              Here is my final approach function validChain (object, path) { return path.split('.').reduce((a, b) => (a || { })[b], object) !== undefined }
                                              – James Harrington
                                              Nov 10 '17 at 21:45










                                              up vote
                                              2
                                              down vote













                                              The answer given by CMS works fine with the following modification for null checks as well



                                              function checkNested(obj /*, level1, level2, ... levelN*/) 
                                              {
                                              var args = Array.prototype.slice.call(arguments),
                                              obj = args.shift();

                                              for (var i = 0; i < args.length; i++)
                                              {
                                              if (obj == null || !obj.hasOwnProperty(args[i]) )
                                              {
                                              return false;
                                              }
                                              obj = obj[args[i]];
                                              }
                                              return true;
                                              }





                                              share|improve this answer

























                                                up vote
                                                2
                                                down vote













                                                The answer given by CMS works fine with the following modification for null checks as well



                                                function checkNested(obj /*, level1, level2, ... levelN*/) 
                                                {
                                                var args = Array.prototype.slice.call(arguments),
                                                obj = args.shift();

                                                for (var i = 0; i < args.length; i++)
                                                {
                                                if (obj == null || !obj.hasOwnProperty(args[i]) )
                                                {
                                                return false;
                                                }
                                                obj = obj[args[i]];
                                                }
                                                return true;
                                                }





                                                share|improve this answer























                                                  up vote
                                                  2
                                                  down vote










                                                  up vote
                                                  2
                                                  down vote









                                                  The answer given by CMS works fine with the following modification for null checks as well



                                                  function checkNested(obj /*, level1, level2, ... levelN*/) 
                                                  {
                                                  var args = Array.prototype.slice.call(arguments),
                                                  obj = args.shift();

                                                  for (var i = 0; i < args.length; i++)
                                                  {
                                                  if (obj == null || !obj.hasOwnProperty(args[i]) )
                                                  {
                                                  return false;
                                                  }
                                                  obj = obj[args[i]];
                                                  }
                                                  return true;
                                                  }





                                                  share|improve this answer












                                                  The answer given by CMS works fine with the following modification for null checks as well



                                                  function checkNested(obj /*, level1, level2, ... levelN*/) 
                                                  {
                                                  var args = Array.prototype.slice.call(arguments),
                                                  obj = args.shift();

                                                  for (var i = 0; i < args.length; i++)
                                                  {
                                                  if (obj == null || !obj.hasOwnProperty(args[i]) )
                                                  {
                                                  return false;
                                                  }
                                                  obj = obj[args[i]];
                                                  }
                                                  return true;
                                                  }






                                                  share|improve this answer












                                                  share|improve this answer



                                                  share|improve this answer










                                                  answered Jun 21 '13 at 18:01









                                                  Anand Sunderraman

                                                  3,2962667128




                                                  3,2962667128






















                                                      up vote
                                                      2
                                                      down vote













                                                      Following options were elaborated starting from this answer. Same tree for both :



                                                      var o = { a: { b: { c: 1 } } };




                                                      Stop searching when undefined



                                                      var u = undefined;
                                                      o.a ? o.a.b ? o.a.b.c : u : u // 1
                                                      o.x ? o.x.y ? o.x.y.z : u : u // undefined
                                                      (o = o.a) ? (o = o.b) ? o.c : u : u // 1




                                                      Ensure each level one by one



                                                      var $ = function (empty) {
                                                      return function (node) {
                                                      return node || empty;
                                                      };
                                                      }({});

                                                      $($(o.a).b).c // 1
                                                      $($(o.x).y).z // undefined





                                                      share|improve this answer



























                                                        up vote
                                                        2
                                                        down vote













                                                        Following options were elaborated starting from this answer. Same tree for both :



                                                        var o = { a: { b: { c: 1 } } };




                                                        Stop searching when undefined



                                                        var u = undefined;
                                                        o.a ? o.a.b ? o.a.b.c : u : u // 1
                                                        o.x ? o.x.y ? o.x.y.z : u : u // undefined
                                                        (o = o.a) ? (o = o.b) ? o.c : u : u // 1




                                                        Ensure each level one by one



                                                        var $ = function (empty) {
                                                        return function (node) {
                                                        return node || empty;
                                                        };
                                                        }({});

                                                        $($(o.a).b).c // 1
                                                        $($(o.x).y).z // undefined





                                                        share|improve this answer

























                                                          up vote
                                                          2
                                                          down vote










                                                          up vote
                                                          2
                                                          down vote









                                                          Following options were elaborated starting from this answer. Same tree for both :



                                                          var o = { a: { b: { c: 1 } } };




                                                          Stop searching when undefined



                                                          var u = undefined;
                                                          o.a ? o.a.b ? o.a.b.c : u : u // 1
                                                          o.x ? o.x.y ? o.x.y.z : u : u // undefined
                                                          (o = o.a) ? (o = o.b) ? o.c : u : u // 1




                                                          Ensure each level one by one



                                                          var $ = function (empty) {
                                                          return function (node) {
                                                          return node || empty;
                                                          };
                                                          }({});

                                                          $($(o.a).b).c // 1
                                                          $($(o.x).y).z // undefined





                                                          share|improve this answer














                                                          Following options were elaborated starting from this answer. Same tree for both :



                                                          var o = { a: { b: { c: 1 } } };




                                                          Stop searching when undefined



                                                          var u = undefined;
                                                          o.a ? o.a.b ? o.a.b.c : u : u // 1
                                                          o.x ? o.x.y ? o.x.y.z : u : u // undefined
                                                          (o = o.a) ? (o = o.b) ? o.c : u : u // 1




                                                          Ensure each level one by one



                                                          var $ = function (empty) {
                                                          return function (node) {
                                                          return node || empty;
                                                          };
                                                          }({});

                                                          $($(o.a).b).c // 1
                                                          $($(o.x).y).z // undefined






                                                          share|improve this answer














                                                          share|improve this answer



                                                          share|improve this answer








                                                          edited May 23 '17 at 10:31









                                                          Community

                                                          11




                                                          11










                                                          answered Sep 7 '13 at 14:04









                                                          leaf

                                                          11k43969




                                                          11k43969






















                                                              up vote
                                                              2
                                                              down vote













                                                              I know this question is old, but I wanted to offer an extension by adding this to all objects. I know people tend to frown on using the Object prototype for extended object functionality, but I don't find anything easier than doing this. Plus, it's now allowed for with the Object.defineProperty method.



                                                              Object.defineProperty( Object.prototype, "has", { value: function( needle ) {
                                                              var obj = this;
                                                              var needles = needle.split( "." );
                                                              for( var i = 0; i<needles.length; i++ ) {
                                                              if( !obj.hasOwnProperty(needles[i])) {
                                                              return false;
                                                              }
                                                              obj = obj[needles[i]];
                                                              }
                                                              return true;
                                                              }});


                                                              Now, in order to test for any property in any object you can simply do:



                                                              if( obj.has("some.deep.nested.object.somewhere") )


                                                              Here's a jsfiddle to test it out, and in particular it includes some jQuery that breaks if you modify the Object.prototype directly because of the property becoming enumerable. This should work fine with 3rd party libraries.






                                                              share|improve this answer





















                                                              • This won't work with array access ([0])
                                                                – Royi Namir
                                                                Oct 2 '15 at 15:15















                                                              up vote
                                                              2
                                                              down vote













                                                              I know this question is old, but I wanted to offer an extension by adding this to all objects. I know people tend to frown on using the Object prototype for extended object functionality, but I don't find anything easier than doing this. Plus, it's now allowed for with the Object.defineProperty method.



                                                              Object.defineProperty( Object.prototype, "has", { value: function( needle ) {
                                                              var obj = this;
                                                              var needles = needle.split( "." );
                                                              for( var i = 0; i<needles.length; i++ ) {
                                                              if( !obj.hasOwnProperty(needles[i])) {
                                                              return false;
                                                              }
                                                              obj = obj[needles[i]];
                                                              }
                                                              return true;
                                                              }});


                                                              Now, in order to test for any property in any object you can simply do:



                                                              if( obj.has("some.deep.nested.object.somewhere") )


                                                              Here's a jsfiddle to test it out, and in particular it includes some jQuery that breaks if you modify the Object.prototype directly because of the property becoming enumerable. This should work fine with 3rd party libraries.






                                                              share|improve this answer





















                                                              • This won't work with array access ([0])
                                                                – Royi Namir
                                                                Oct 2 '15 at 15:15













                                                              up vote
                                                              2
                                                              down vote










                                                              up vote
                                                              2
                                                              down vote









                                                              I know this question is old, but I wanted to offer an extension by adding this to all objects. I know people tend to frown on using the Object prototype for extended object functionality, but I don't find anything easier than doing this. Plus, it's now allowed for with the Object.defineProperty method.



                                                              Object.defineProperty( Object.prototype, "has", { value: function( needle ) {
                                                              var obj = this;
                                                              var needles = needle.split( "." );
                                                              for( var i = 0; i<needles.length; i++ ) {
                                                              if( !obj.hasOwnProperty(needles[i])) {
                                                              return false;
                                                              }
                                                              obj = obj[needles[i]];
                                                              }
                                                              return true;
                                                              }});


                                                              Now, in order to test for any property in any object you can simply do:



                                                              if( obj.has("some.deep.nested.object.somewhere") )


                                                              Here's a jsfiddle to test it out, and in particular it includes some jQuery that breaks if you modify the Object.prototype directly because of the property becoming enumerable. This should work fine with 3rd party libraries.






                                                              share|improve this answer












                                                              I know this question is old, but I wanted to offer an extension by adding this to all objects. I know people tend to frown on using the Object prototype for extended object functionality, but I don't find anything easier than doing this. Plus, it's now allowed for with the Object.defineProperty method.



                                                              Object.defineProperty( Object.prototype, "has", { value: function( needle ) {
                                                              var obj = this;
                                                              var needles = needle.split( "." );
                                                              for( var i = 0; i<needles.length; i++ ) {
                                                              if( !obj.hasOwnProperty(needles[i])) {
                                                              return false;
                                                              }
                                                              obj = obj[needles[i]];
                                                              }
                                                              return true;
                                                              }});


                                                              Now, in order to test for any property in any object you can simply do:



                                                              if( obj.has("some.deep.nested.object.somewhere") )


                                                              Here's a jsfiddle to test it out, and in particular it includes some jQuery that breaks if you modify the Object.prototype directly because of the property becoming enumerable. This should work fine with 3rd party libraries.







                                                              share|improve this answer












                                                              share|improve this answer



                                                              share|improve this answer










                                                              answered Mar 24 '15 at 15:57









                                                              Brian Sidebotham

                                                              1,091714




                                                              1,091714












                                                              • This won't work with array access ([0])
                                                                – Royi Namir
                                                                Oct 2 '15 at 15:15


















                                                              • This won't work with array access ([0])
                                                                – Royi Namir
                                                                Oct 2 '15 at 15:15
















                                                              This won't work with array access ([0])
                                                              – Royi Namir
                                                              Oct 2 '15 at 15:15




                                                              This won't work with array access ([0])
                                                              – Royi Namir
                                                              Oct 2 '15 at 15:15










                                                              up vote
                                                              2
                                                              down vote













                                                              I think this is a slight improvement (becomes a 1-liner):



                                                                 alert( test.level1 && test.level1.level2 && test.level1.level2.level3 )


                                                              This works because the && operator returns the final operand it evaluated (and it short-circuits).






                                                              share|improve this answer

























                                                                up vote
                                                                2
                                                                down vote













                                                                I think this is a slight improvement (becomes a 1-liner):



                                                                   alert( test.level1 && test.level1.level2 && test.level1.level2.level3 )


                                                                This works because the && operator returns the final operand it evaluated (and it short-circuits).






                                                                share|improve this answer























                                                                  up vote
                                                                  2
                                                                  down vote










                                                                  up vote
                                                                  2
                                                                  down vote









                                                                  I think this is a slight improvement (becomes a 1-liner):



                                                                     alert( test.level1 && test.level1.level2 && test.level1.level2.level3 )


                                                                  This works because the && operator returns the final operand it evaluated (and it short-circuits).






                                                                  share|improve this answer












                                                                  I think this is a slight improvement (becomes a 1-liner):



                                                                     alert( test.level1 && test.level1.level2 && test.level1.level2.level3 )


                                                                  This works because the && operator returns the final operand it evaluated (and it short-circuits).







                                                                  share|improve this answer












                                                                  share|improve this answer



                                                                  share|improve this answer










                                                                  answered Jul 16 '15 at 19:05









                                                                  Julius Musseau

                                                                  3,0951522




                                                                  3,0951522






















                                                                      up vote
                                                                      2
                                                                      down vote













                                                                      This works with all objects and arrays :)



                                                                      ex:



                                                                      if( obj._has( "something.['deep']['under'][1][0].item" ) ) {
                                                                      //do something
                                                                      }


                                                                      this is my improved version of Brian's answer



                                                                      I used _has as the property name because it can conflict with existing has property (ex: maps)



                                                                      Object.defineProperty( Object.prototype, "_has", { value: function( needle ) {
                                                                      var obj = this;
                                                                      var needles = needle.split( "." );
                                                                      var needles_full=;
                                                                      var needles_square;
                                                                      for( var i = 0; i<needles.length; i++ ) {
                                                                      needles_square = needles[i].split( "[" );
                                                                      if(needles_square.length>1){
                                                                      for( var j = 0; j<needles_square.length; j++ ) {
                                                                      if(needles_square[j].length){
                                                                      needles_full.push(needles_square[j]);
                                                                      }
                                                                      }
                                                                      }else{
                                                                      needles_full.push(needles[i]);
                                                                      }
                                                                      }
                                                                      for( var i = 0; i<needles_full.length; i++ ) {
                                                                      var res = needles_full[i].match(/^((d+)|"(.+)"|'(.+)')]$/);
                                                                      if (res != null) {
                                                                      for (var j = 0; j < res.length; j++) {
                                                                      if (res[j] != undefined) {
                                                                      needles_full[i] = res[j];
                                                                      }
                                                                      }
                                                                      }

                                                                      if( typeof obj[needles_full[i]]=='undefined') {
                                                                      return false;
                                                                      }
                                                                      obj = obj[needles_full[i]];
                                                                      }
                                                                      return true;
                                                                      }});


                                                                      Here's the fiddle






                                                                      share|improve this answer



























                                                                        up vote
                                                                        2
                                                                        down vote













                                                                        This works with all objects and arrays :)



                                                                        ex:



                                                                        if( obj._has( "something.['deep']['under'][1][0].item" ) ) {
                                                                        //do something
                                                                        }


                                                                        this is my improved version of Brian's answer



                                                                        I used _has as the property name because it can conflict with existing has property (ex: maps)



                                                                        Object.defineProperty( Object.prototype, "_has", { value: function( needle ) {
                                                                        var obj = this;
                                                                        var needles = needle.split( "." );
                                                                        var needles_full=;
                                                                        var needles_square;
                                                                        for( var i = 0; i<needles.length; i++ ) {
                                                                        needles_square = needles[i].split( "[" );
                                                                        if(needles_square.length>1){
                                                                        for( var j = 0; j<needles_square.length; j++ ) {
                                                                        if(needles_square[j].length){
                                                                        needles_full.push(needles_square[j]);
                                                                        }
                                                                        }
                                                                        }else{
                                                                        needles_full.push(needles[i]);
                                                                        }
                                                                        }
                                                                        for( var i = 0; i<needles_full.length; i++ ) {
                                                                        var res = needles_full[i].match(/^((d+)|"(.+)"|'(.+)')]$/);
                                                                        if (res != null) {
                                                                        for (var j = 0; j < res.length; j++) {
                                                                        if (res[j] != undefined) {
                                                                        needles_full[i] = res[j];
                                                                        }
                                                                        }
                                                                        }

                                                                        if( typeof obj[needles_full[i]]=='undefined') {
                                                                        return false;
                                                                        }
                                                                        obj = obj[needles_full[i]];
                                                                        }
                                                                        return true;
                                                                        }});


                                                                        Here's the fiddle






                                                                        share|improve this answer

























                                                                          up vote
                                                                          2
                                                                          down vote










                                                                          up vote
                                                                          2
                                                                          down vote









                                                                          This works with all objects and arrays :)



                                                                          ex:



                                                                          if( obj._has( "something.['deep']['under'][1][0].item" ) ) {
                                                                          //do something
                                                                          }


                                                                          this is my improved version of Brian's answer



                                                                          I used _has as the property name because it can conflict with existing has property (ex: maps)



                                                                          Object.defineProperty( Object.prototype, "_has", { value: function( needle ) {
                                                                          var obj = this;
                                                                          var needles = needle.split( "." );
                                                                          var needles_full=;
                                                                          var needles_square;
                                                                          for( var i = 0; i<needles.length; i++ ) {
                                                                          needles_square = needles[i].split( "[" );
                                                                          if(needles_square.length>1){
                                                                          for( var j = 0; j<needles_square.length; j++ ) {
                                                                          if(needles_square[j].length){
                                                                          needles_full.push(needles_square[j]);
                                                                          }
                                                                          }
                                                                          }else{
                                                                          needles_full.push(needles[i]);
                                                                          }
                                                                          }
                                                                          for( var i = 0; i<needles_full.length; i++ ) {
                                                                          var res = needles_full[i].match(/^((d+)|"(.+)"|'(.+)')]$/);
                                                                          if (res != null) {
                                                                          for (var j = 0; j < res.length; j++) {
                                                                          if (res[j] != undefined) {
                                                                          needles_full[i] = res[j];
                                                                          }
                                                                          }
                                                                          }

                                                                          if( typeof obj[needles_full[i]]=='undefined') {
                                                                          return false;
                                                                          }
                                                                          obj = obj[needles_full[i]];
                                                                          }
                                                                          return true;
                                                                          }});


                                                                          Here's the fiddle






                                                                          share|improve this answer














                                                                          This works with all objects and arrays :)



                                                                          ex:



                                                                          if( obj._has( "something.['deep']['under'][1][0].item" ) ) {
                                                                          //do something
                                                                          }


                                                                          this is my improved version of Brian's answer



                                                                          I used _has as the property name because it can conflict with existing has property (ex: maps)



                                                                          Object.defineProperty( Object.prototype, "_has", { value: function( needle ) {
                                                                          var obj = this;
                                                                          var needles = needle.split( "." );
                                                                          var needles_full=;
                                                                          var needles_square;
                                                                          for( var i = 0; i<needles.length; i++ ) {
                                                                          needles_square = needles[i].split( "[" );
                                                                          if(needles_square.length>1){
                                                                          for( var j = 0; j<needles_square.length; j++ ) {
                                                                          if(needles_square[j].length){
                                                                          needles_full.push(needles_square[j]);
                                                                          }
                                                                          }
                                                                          }else{
                                                                          needles_full.push(needles[i]);
                                                                          }
                                                                          }
                                                                          for( var i = 0; i<needles_full.length; i++ ) {
                                                                          var res = needles_full[i].match(/^((d+)|"(.+)"|'(.+)')]$/);
                                                                          if (res != null) {
                                                                          for (var j = 0; j < res.length; j++) {
                                                                          if (res[j] != undefined) {
                                                                          needles_full[i] = res[j];
                                                                          }
                                                                          }
                                                                          }

                                                                          if( typeof obj[needles_full[i]]=='undefined') {
                                                                          return false;
                                                                          }
                                                                          obj = obj[needles_full[i]];
                                                                          }
                                                                          return true;
                                                                          }});


                                                                          Here's the fiddle







                                                                          share|improve this answer














                                                                          share|improve this answer



                                                                          share|improve this answer








                                                                          edited Feb 24 '16 at 14:08

























                                                                          answered Jan 30 '16 at 13:37









                                                                          adutu

                                                                          36638




                                                                          36638






















                                                                              up vote
                                                                              2
                                                                              down vote













                                                                              Here's my take on it - most of these solutions ignore the case of a nested array as in:



                                                                                  obj = {
                                                                              "l1":"something",
                                                                              "l2":[{k:0},{k:1}],
                                                                              "l3":{
                                                                              "subL":"hello"
                                                                              }
                                                                              }


                                                                              I may want to check for obj.l2[0].k



                                                                              With the function below, you can do deeptest('l2[0].k',obj)



                                                                              The function will return true if the object exists, false otherwise






                                                                              function deeptest(keyPath, testObj) {
                                                                              var obj;

                                                                              keyPath = keyPath.split('.')
                                                                              var cKey = keyPath.shift();

                                                                              function get(pObj, pKey) {
                                                                              var bracketStart, bracketEnd, o;

                                                                              bracketStart = pKey.indexOf("[");
                                                                              if (bracketStart > -1) { //check for nested arrays
                                                                              bracketEnd = pKey.indexOf("]");
                                                                              var arrIndex = pKey.substr(bracketStart + 1, bracketEnd - bracketStart - 1);
                                                                              pKey = pKey.substr(0, bracketStart);
                                                                              var n = pObj[pKey];
                                                                              o = n? n[arrIndex] : undefined;

                                                                              } else {
                                                                              o = pObj[pKey];
                                                                              }
                                                                              return o;
                                                                              }

                                                                              obj = get(testObj, cKey);
                                                                              while (obj && keyPath.length) {
                                                                              obj = get(obj, keyPath.shift());
                                                                              }
                                                                              return typeof(obj) !== 'undefined';
                                                                              }

                                                                              var obj = {
                                                                              "l1":"level1",
                                                                              "arr1":[
                                                                              {"k":0},
                                                                              {"k":1},
                                                                              {"k":2}
                                                                              ],
                                                                              "sub": {
                                                                              "a":"letter A",
                                                                              "b":"letter B"
                                                                              }
                                                                              };
                                                                              console.log("l1: " + deeptest("l1",obj));
                                                                              console.log("arr1[0]: " + deeptest("arr1[0]",obj));
                                                                              console.log("arr1[1].k: " + deeptest("arr1[1].k",obj));
                                                                              console.log("arr1[1].j: " + deeptest("arr1[1].j",obj));
                                                                              console.log("arr1[3]: " + deeptest("arr1[3]",obj));
                                                                              console.log("arr2: " + deeptest("arr2",obj));








                                                                              share|improve this answer



























                                                                                up vote
                                                                                2
                                                                                down vote













                                                                                Here's my take on it - most of these solutions ignore the case of a nested array as in:



                                                                                    obj = {
                                                                                "l1":"something",
                                                                                "l2":[{k:0},{k:1}],
                                                                                "l3":{
                                                                                "subL":"hello"
                                                                                }
                                                                                }


                                                                                I may want to check for obj.l2[0].k



                                                                                With the function below, you can do deeptest('l2[0].k',obj)



                                                                                The function will return true if the object exists, false otherwise






                                                                                function deeptest(keyPath, testObj) {
                                                                                var obj;

                                                                                keyPath = keyPath.split('.')
                                                                                var cKey = keyPath.shift();

                                                                                function get(pObj, pKey) {
                                                                                var bracketStart, bracketEnd, o;

                                                                                bracketStart = pKey.indexOf("[");
                                                                                if (bracketStart > -1) { //check for nested arrays
                                                                                bracketEnd = pKey.indexOf("]");
                                                                                var arrIndex = pKey.substr(bracketStart + 1, bracketEnd - bracketStart - 1);
                                                                                pKey = pKey.substr(0, bracketStart);
                                                                                var n = pObj[pKey];
                                                                                o = n? n[arrIndex] : undefined;

                                                                                } else {
                                                                                o = pObj[pKey];
                                                                                }
                                                                                return o;
                                                                                }

                                                                                obj = get(testObj, cKey);
                                                                                while (obj && keyPath.length) {
                                                                                obj = get(obj, keyPath.shift());
                                                                                }
                                                                                return typeof(obj) !== 'undefined';
                                                                                }

                                                                                var obj = {
                                                                                "l1":"level1",
                                                                                "arr1":[
                                                                                {"k":0},
                                                                                {"k":1},
                                                                                {"k":2}
                                                                                ],
                                                                                "sub": {
                                                                                "a":"letter A",
                                                                                "b":"letter B"
                                                                                }
                                                                                };
                                                                                console.log("l1: " + deeptest("l1",obj));
                                                                                console.log("arr1[0]: " + deeptest("arr1[0]",obj));
                                                                                console.log("arr1[1].k: " + deeptest("arr1[1].k",obj));
                                                                                console.log("arr1[1].j: " + deeptest("arr1[1].j",obj));
                                                                                console.log("arr1[3]: " + deeptest("arr1[3]",obj));
                                                                                console.log("arr2: " + deeptest("arr2",obj));








                                                                                share|improve this answer

























                                                                                  up vote
                                                                                  2
                                                                                  down vote










                                                                                  up vote
                                                                                  2
                                                                                  down vote









                                                                                  Here's my take on it - most of these solutions ignore the case of a nested array as in:



                                                                                      obj = {
                                                                                  "l1":"something",
                                                                                  "l2":[{k:0},{k:1}],
                                                                                  "l3":{
                                                                                  "subL":"hello"
                                                                                  }
                                                                                  }


                                                                                  I may want to check for obj.l2[0].k



                                                                                  With the function below, you can do deeptest('l2[0].k',obj)



                                                                                  The function will return true if the object exists, false otherwise






                                                                                  function deeptest(keyPath, testObj) {
                                                                                  var obj;

                                                                                  keyPath = keyPath.split('.')
                                                                                  var cKey = keyPath.shift();

                                                                                  function get(pObj, pKey) {
                                                                                  var bracketStart, bracketEnd, o;

                                                                                  bracketStart = pKey.indexOf("[");
                                                                                  if (bracketStart > -1) { //check for nested arrays
                                                                                  bracketEnd = pKey.indexOf("]");
                                                                                  var arrIndex = pKey.substr(bracketStart + 1, bracketEnd - bracketStart - 1);
                                                                                  pKey = pKey.substr(0, bracketStart);
                                                                                  var n = pObj[pKey];
                                                                                  o = n? n[arrIndex] : undefined;

                                                                                  } else {
                                                                                  o = pObj[pKey];
                                                                                  }
                                                                                  return o;
                                                                                  }

                                                                                  obj = get(testObj, cKey);
                                                                                  while (obj && keyPath.length) {
                                                                                  obj = get(obj, keyPath.shift());
                                                                                  }
                                                                                  return typeof(obj) !== 'undefined';
                                                                                  }

                                                                                  var obj = {
                                                                                  "l1":"level1",
                                                                                  "arr1":[
                                                                                  {"k":0},
                                                                                  {"k":1},
                                                                                  {"k":2}
                                                                                  ],
                                                                                  "sub": {
                                                                                  "a":"letter A",
                                                                                  "b":"letter B"
                                                                                  }
                                                                                  };
                                                                                  console.log("l1: " + deeptest("l1",obj));
                                                                                  console.log("arr1[0]: " + deeptest("arr1[0]",obj));
                                                                                  console.log("arr1[1].k: " + deeptest("arr1[1].k",obj));
                                                                                  console.log("arr1[1].j: " + deeptest("arr1[1].j",obj));
                                                                                  console.log("arr1[3]: " + deeptest("arr1[3]",obj));
                                                                                  console.log("arr2: " + deeptest("arr2",obj));








                                                                                  share|improve this answer














                                                                                  Here's my take on it - most of these solutions ignore the case of a nested array as in:



                                                                                      obj = {
                                                                                  "l1":"something",
                                                                                  "l2":[{k:0},{k:1}],
                                                                                  "l3":{
                                                                                  "subL":"hello"
                                                                                  }
                                                                                  }


                                                                                  I may want to check for obj.l2[0].k



                                                                                  With the function below, you can do deeptest('l2[0].k',obj)



                                                                                  The function will return true if the object exists, false otherwise






                                                                                  function deeptest(keyPath, testObj) {
                                                                                  var obj;

                                                                                  keyPath = keyPath.split('.')
                                                                                  var cKey = keyPath.shift();

                                                                                  function get(pObj, pKey) {
                                                                                  var bracketStart, bracketEnd, o;

                                                                                  bracketStart = pKey.indexOf("[");
                                                                                  if (bracketStart > -1) { //check for nested arrays
                                                                                  bracketEnd = pKey.indexOf("]");
                                                                                  var arrIndex = pKey.substr(bracketStart + 1, bracketEnd - bracketStart - 1);
                                                                                  pKey = pKey.substr(0, bracketStart);
                                                                                  var n = pObj[pKey];
                                                                                  o = n? n[arrIndex] : undefined;

                                                                                  } else {
                                                                                  o = pObj[pKey];
                                                                                  }
                                                                                  return o;
                                                                                  }

                                                                                  obj = get(testObj, cKey);
                                                                                  while (obj && keyPath.length) {
                                                                                  obj = get(obj, keyPath.shift());
                                                                                  }
                                                                                  return typeof(obj) !== 'undefined';
                                                                                  }

                                                                                  var obj = {
                                                                                  "l1":"level1",
                                                                                  "arr1":[
                                                                                  {"k":0},
                                                                                  {"k":1},
                                                                                  {"k":2}
                                                                                  ],
                                                                                  "sub": {
                                                                                  "a":"letter A",
                                                                                  "b":"letter B"
                                                                                  }
                                                                                  };
                                                                                  console.log("l1: " + deeptest("l1",obj));
                                                                                  console.log("arr1[0]: " + deeptest("arr1[0]",obj));
                                                                                  console.log("arr1[1].k: " + deeptest("arr1[1].k",obj));
                                                                                  console.log("arr1[1].j: " + deeptest("arr1[1].j",obj));
                                                                                  console.log("arr1[3]: " + deeptest("arr1[3]",obj));
                                                                                  console.log("arr2: " + deeptest("arr2",obj));








                                                                                  function deeptest(keyPath, testObj) {
                                                                                  var obj;

                                                                                  keyPath = keyPath.split('.')
                                                                                  var cKey = keyPath.shift();

                                                                                  function get(pObj, pKey) {
                                                                                  var bracketStart, bracketEnd, o;

                                                                                  bracketStart = pKey.indexOf("[");
                                                                                  if (bracketStart > -1) { //check for nested arrays
                                                                                  bracketEnd = pKey.indexOf("]");
                                                                                  var arrIndex = pKey.substr(bracketStart + 1, bracketEnd - bracketStart - 1);
                                                                                  pKey = pKey.substr(0, bracketStart);
                                                                                  var n = pObj[pKey];
                                                                                  o = n? n[arrIndex] : undefined;

                                                                                  } else {
                                                                                  o = pObj[pKey];
                                                                                  }
                                                                                  return o;
                                                                                  }

                                                                                  obj = get(testObj, cKey);
                                                                                  while (obj && keyPath.length) {
                                                                                  obj = get(obj, keyPath.shift());
                                                                                  }
                                                                                  return typeof(obj) !== 'undefined';
                                                                                  }

                                                                                  var obj = {
                                                                                  "l1":"level1",
                                                                                  "arr1":[
                                                                                  {"k":0},
                                                                                  {"k":1},
                                                                                  {"k":2}
                                                                                  ],
                                                                                  "sub": {
                                                                                  "a":"letter A",
                                                                                  "b":"letter B"
                                                                                  }
                                                                                  };
                                                                                  console.log("l1: " + deeptest("l1",obj));
                                                                                  console.log("arr1[0]: " + deeptest("arr1[0]",obj));
                                                                                  console.log("arr1[1].k: " + deeptest("arr1[1].k",obj));
                                                                                  console.log("arr1[1].j: " + deeptest("arr1[1].j",obj));
                                                                                  console.log("arr1[3]: " + deeptest("arr1[3]",obj));
                                                                                  console.log("arr2: " + deeptest("arr2",obj));





                                                                                  function deeptest(keyPath, testObj) {
                                                                                  var obj;

                                                                                  keyPath = keyPath.split('.')
                                                                                  var cKey = keyPath.shift();

                                                                                  function get(pObj, pKey) {
                                                                                  var bracketStart, bracketEnd, o;

                                                                                  bracketStart = pKey.indexOf("[");
                                                                                  if (bracketStart > -1) { //check for nested arrays
                                                                                  bracketEnd = pKey.indexOf("]");
                                                                                  var arrIndex = pKey.substr(bracketStart + 1, bracketEnd - bracketStart - 1);
                                                                                  pKey = pKey.substr(0, bracketStart);
                                                                                  var n = pObj[pKey];
                                                                                  o = n? n[arrIndex] : undefined;

                                                                                  } else {
                                                                                  o = pObj[pKey];
                                                                                  }
                                                                                  return o;
                                                                                  }

                                                                                  obj = get(testObj, cKey);
                                                                                  while (obj && keyPath.length) {
                                                                                  obj = get(obj, keyPath.shift());
                                                                                  }
                                                                                  return typeof(obj) !== 'undefined';
                                                                                  }

                                                                                  var obj = {
                                                                                  "l1":"level1",
                                                                                  "arr1":[
                                                                                  {"k":0},
                                                                                  {"k":1},
                                                                                  {"k":2}
                                                                                  ],
                                                                                  "sub": {
                                                                                  "a":"letter A",
                                                                                  "b":"letter B"
                                                                                  }
                                                                                  };
                                                                                  console.log("l1: " + deeptest("l1",obj));
                                                                                  console.log("arr1[0]: " + deeptest("arr1[0]",obj));
                                                                                  console.log("arr1[1].k: " + deeptest("arr1[1].k",obj));
                                                                                  console.log("arr1[1].j: " + deeptest("arr1[1].j",obj));
                                                                                  console.log("arr1[3]: " + deeptest("arr1[3]",obj));
                                                                                  console.log("arr2: " + deeptest("arr2",obj));






                                                                                  share|improve this answer














                                                                                  share|improve this answer



                                                                                  share|improve this answer








                                                                                  edited Aug 25 '16 at 2:49









                                                                                  Seth

                                                                                  6,00663058




                                                                                  6,00663058










                                                                                  answered Nov 9 '15 at 18:24









                                                                                  Mike D

                                                                                  394




                                                                                  394






















                                                                                      up vote
                                                                                      2
                                                                                      down vote













                                                                                      Now we can also use reduce to loop through nested keys:






                                                                                      // @params o<object>
                                                                                      // @params path<string> expects 'obj.prop1.prop2.prop3'
                                                                                      // returns: obj[path] value or 'false' if prop doesn't exist

                                                                                      const objPropIfExists = o => path => {
                                                                                      const levels = path.split('.');
                                                                                      const res = (levels.length > 0)
                                                                                      ? levels.reduce((a, c) => a[c] || 0, o)
                                                                                      : o[path];
                                                                                      return (!!res) ? res : false
                                                                                      }

                                                                                      const obj = {
                                                                                      name: 'Name',
                                                                                      sys: { country: 'AU' },
                                                                                      main: { temp: '34', temp_min: '13' },
                                                                                      visibility: '35%'
                                                                                      }

                                                                                      const exists = objPropIfExists(obj)('main.temp')
                                                                                      const doesntExist = objPropIfExists(obj)('main.temp.foo.bar.baz')

                                                                                      console.log(exists, doesntExist)








                                                                                      share|improve this answer

























                                                                                        up vote
                                                                                        2
                                                                                        down vote













                                                                                        Now we can also use reduce to loop through nested keys:






                                                                                        // @params o<object>
                                                                                        // @params path<string> expects 'obj.prop1.prop2.prop3'
                                                                                        // returns: obj[path] value or 'false' if prop doesn't exist

                                                                                        const objPropIfExists = o => path => {
                                                                                        const levels = path.split('.');
                                                                                        const res = (levels.length > 0)
                                                                                        ? levels.reduce((a, c) => a[c] || 0, o)
                                                                                        : o[path];
                                                                                        return (!!res) ? res : false
                                                                                        }

                                                                                        const obj = {
                                                                                        name: 'Name',
                                                                                        sys: { country: 'AU' },
                                                                                        main: { temp: '34', temp_min: '13' },
                                                                                        visibility: '35%'
                                                                                        }

                                                                                        const exists = objPropIfExists(obj)('main.temp')
                                                                                        const doesntExist = objPropIfExists(obj)('main.temp.foo.bar.baz')

                                                                                        console.log(exists, doesntExist)








                                                                                        share|improve this answer























                                                                                          up vote
                                                                                          2
                                                                                          down vote










                                                                                          up vote
                                                                                          2
                                                                                          down vote









                                                                                          Now we can also use reduce to loop through nested keys:






                                                                                          // @params o<object>
                                                                                          // @params path<string> expects 'obj.prop1.prop2.prop3'
                                                                                          // returns: obj[path] value or 'false' if prop doesn't exist

                                                                                          const objPropIfExists = o => path => {
                                                                                          const levels = path.split('.');
                                                                                          const res = (levels.length > 0)
                                                                                          ? levels.reduce((a, c) => a[c] || 0, o)
                                                                                          : o[path];
                                                                                          return (!!res) ? res : false
                                                                                          }

                                                                                          const obj = {
                                                                                          name: 'Name',
                                                                                          sys: { country: 'AU' },
                                                                                          main: { temp: '34', temp_min: '13' },
                                                                                          visibility: '35%'
                                                                                          }

                                                                                          const exists = objPropIfExists(obj)('main.temp')
                                                                                          const doesntExist = objPropIfExists(obj)('main.temp.foo.bar.baz')

                                                                                          console.log(exists, doesntExist)








                                                                                          share|improve this answer












                                                                                          Now we can also use reduce to loop through nested keys:






                                                                                          // @params o<object>
                                                                                          // @params path<string> expects 'obj.prop1.prop2.prop3'
                                                                                          // returns: obj[path] value or 'false' if prop doesn't exist

                                                                                          const objPropIfExists = o => path => {
                                                                                          const levels = path.split('.');
                                                                                          const res = (levels.length > 0)
                                                                                          ? levels.reduce((a, c) => a[c] || 0, o)
                                                                                          : o[path];
                                                                                          return (!!res) ? res : false
                                                                                          }

                                                                                          const obj = {
                                                                                          name: 'Name',
                                                                                          sys: { country: 'AU' },
                                                                                          main: { temp: '34', temp_min: '13' },
                                                                                          visibility: '35%'
                                                                                          }

                                                                                          const exists = objPropIfExists(obj)('main.temp')
                                                                                          const doesntExist = objPropIfExists(obj)('main.temp.foo.bar.baz')

                                                                                          console.log(exists, doesntExist)








                                                                                          // @params o<object>
                                                                                          // @params path<string> expects 'obj.prop1.prop2.prop3'
                                                                                          // returns: obj[path] value or 'false' if prop doesn't exist

                                                                                          const objPropIfExists = o => path => {
                                                                                          const levels = path.split('.');
                                                                                          const res = (levels.length > 0)
                                                                                          ? levels.reduce((a, c) => a[c] || 0, o)
                                                                                          : o[path];
                                                                                          return (!!res) ? res : false
                                                                                          }

                                                                                          const obj = {
                                                                                          name: 'Name',
                                                                                          sys: { country: 'AU' },
                                                                                          main: { temp: '34', temp_min: '13' },
                                                                                          visibility: '35%'
                                                                                          }

                                                                                          const exists = objPropIfExists(obj)('main.temp')
                                                                                          const doesntExist = objPropIfExists(obj)('main.temp.foo.bar.baz')

                                                                                          console.log(exists, doesntExist)





                                                                                          // @params o<object>
                                                                                          // @params path<string> expects 'obj.prop1.prop2.prop3'
                                                                                          // returns: obj[path] value or 'false' if prop doesn't exist

                                                                                          const objPropIfExists = o => path => {
                                                                                          const levels = path.split('.');
                                                                                          const res = (levels.length > 0)
                                                                                          ? levels.reduce((a, c) => a[c] || 0, o)
                                                                                          : o[path];
                                                                                          return (!!res) ? res : false
                                                                                          }

                                                                                          const obj = {
                                                                                          name: 'Name',
                                                                                          sys: { country: 'AU' },
                                                                                          main: { temp: '34', temp_min: '13' },
                                                                                          visibility: '35%'
                                                                                          }

                                                                                          const exists = objPropIfExists(obj)('main.temp')
                                                                                          const doesntExist = objPropIfExists(obj)('main.temp.foo.bar.baz')

                                                                                          console.log(exists, doesntExist)






                                                                                          share|improve this answer












                                                                                          share|improve this answer



                                                                                          share|improve this answer










                                                                                          answered Apr 30 '17 at 18:42









                                                                                          Egor Stambakio

                                                                                          8,06141321




                                                                                          8,06141321






















                                                                                              up vote
                                                                                              2
                                                                                              down vote













                                                                                              I thought I'd add another one that I came up with today. The reason I am proud of this solution is that it avoids nested brackets that are used in many solutions such as Object Wrap (by Oliver Steele):



                                                                                              (in this example I use an underscore as a placeholder variable, but any variable name will work)






                                                                                              //the 'test' object
                                                                                              var test = {level1: {level2: {level3: 'level3'}}};

                                                                                              let _ = test;

                                                                                              if ((_=_.level1) && (_=_.level2) && (_=_.level3)) {

                                                                                              let level3 = _;
                                                                                              //do stuff with level3

                                                                                              }








                                                                                              //you could also use 'stacked' if statements. This helps if your object goes very deep. 
                                                                                              //(formatted without nesting or curly braces except the last one)

                                                                                              let _ = test;

                                                                                              if (_=_.level1)
                                                                                              if (_=_.level2)
                                                                                              if (_=_.level3) {

                                                                                              let level3 = _;
                                                                                              //do stuff with level3
                                                                                              }


                                                                                              //or you can indent:
                                                                                              if (_=_.level1)
                                                                                              if (_=_.level2)
                                                                                              if (_=_.level3) {

                                                                                              let level3 = _;
                                                                                              //do stuff with level3
                                                                                              }








                                                                                              share|improve this answer



























                                                                                                up vote
                                                                                                2
                                                                                                down vote













                                                                                                I thought I'd add another one that I came up with today. The reason I am proud of this solution is that it avoids nested brackets that are used in many solutions such as Object Wrap (by Oliver Steele):



                                                                                                (in this example I use an underscore as a placeholder variable, but any variable name will work)






                                                                                                //the 'test' object
                                                                                                var test = {level1: {level2: {level3: 'level3'}}};

                                                                                                let _ = test;

                                                                                                if ((_=_.level1) && (_=_.level2) && (_=_.level3)) {

                                                                                                let level3 = _;
                                                                                                //do stuff with level3

                                                                                                }








                                                                                                //you could also use 'stacked' if statements. This helps if your object goes very deep. 
                                                                                                //(formatted without nesting or curly braces except the last one)

                                                                                                let _ = test;

                                                                                                if (_=_.level1)
                                                                                                if (_=_.level2)
                                                                                                if (_=_.level3) {

                                                                                                let level3 = _;
                                                                                                //do stuff with level3
                                                                                                }


                                                                                                //or you can indent:
                                                                                                if (_=_.level1)
                                                                                                if (_=_.level2)
                                                                                                if (_=_.level3) {

                                                                                                let level3 = _;
                                                                                                //do stuff with level3
                                                                                                }








                                                                                                share|improve this answer

























                                                                                                  up vote
                                                                                                  2
                                                                                                  down vote










                                                                                                  up vote
                                                                                                  2
                                                                                                  down vote









                                                                                                  I thought I'd add another one that I came up with today. The reason I am proud of this solution is that it avoids nested brackets that are used in many solutions such as Object Wrap (by Oliver Steele):



                                                                                                  (in this example I use an underscore as a placeholder variable, but any variable name will work)






                                                                                                  //the 'test' object
                                                                                                  var test = {level1: {level2: {level3: 'level3'}}};

                                                                                                  let _ = test;

                                                                                                  if ((_=_.level1) && (_=_.level2) && (_=_.level3)) {

                                                                                                  let level3 = _;
                                                                                                  //do stuff with level3

                                                                                                  }








                                                                                                  //you could also use 'stacked' if statements. This helps if your object goes very deep. 
                                                                                                  //(formatted without nesting or curly braces except the last one)

                                                                                                  let _ = test;

                                                                                                  if (_=_.level1)
                                                                                                  if (_=_.level2)
                                                                                                  if (_=_.level3) {

                                                                                                  let level3 = _;
                                                                                                  //do stuff with level3
                                                                                                  }


                                                                                                  //or you can indent:
                                                                                                  if (_=_.level1)
                                                                                                  if (_=_.level2)
                                                                                                  if (_=_.level3) {

                                                                                                  let level3 = _;
                                                                                                  //do stuff with level3
                                                                                                  }








                                                                                                  share|improve this answer














                                                                                                  I thought I'd add another one that I came up with today. The reason I am proud of this solution is that it avoids nested brackets that are used in many solutions such as Object Wrap (by Oliver Steele):



                                                                                                  (in this example I use an underscore as a placeholder variable, but any variable name will work)






                                                                                                  //the 'test' object
                                                                                                  var test = {level1: {level2: {level3: 'level3'}}};

                                                                                                  let _ = test;

                                                                                                  if ((_=_.level1) && (_=_.level2) && (_=_.level3)) {

                                                                                                  let level3 = _;
                                                                                                  //do stuff with level3

                                                                                                  }








                                                                                                  //you could also use 'stacked' if statements. This helps if your object goes very deep. 
                                                                                                  //(formatted without nesting or curly braces except the last one)

                                                                                                  let _ = test;

                                                                                                  if (_=_.level1)
                                                                                                  if (_=_.level2)
                                                                                                  if (_=_.level3) {

                                                                                                  let level3 = _;
                                                                                                  //do stuff with level3
                                                                                                  }


                                                                                                  //or you can indent:
                                                                                                  if (_=_.level1)
                                                                                                  if (_=_.level2)
                                                                                                  if (_=_.level3) {

                                                                                                  let level3 = _;
                                                                                                  //do stuff with level3
                                                                                                  }








                                                                                                  //the 'test' object
                                                                                                  var test = {level1: {level2: {level3: 'level3'}}};

                                                                                                  let _ = test;

                                                                                                  if ((_=_.level1) && (_=_.level2) && (_=_.level3)) {

                                                                                                  let level3 = _;
                                                                                                  //do stuff with level3

                                                                                                  }





                                                                                                  //the 'test' object
                                                                                                  var test = {level1: {level2: {level3: 'level3'}}};

                                                                                                  let _ = test;

                                                                                                  if ((_=_.level1) && (_=_.level2) && (_=_.level3)) {

                                                                                                  let level3 = _;
                                                                                                  //do stuff with level3

                                                                                                  }





                                                                                                  //you could also use 'stacked' if statements. This helps if your object goes very deep. 
                                                                                                  //(formatted without nesting or curly braces except the last one)

                                                                                                  let _ = test;

                                                                                                  if (_=_.level1)
                                                                                                  if (_=_.level2)
                                                                                                  if (_=_.level3) {

                                                                                                  let level3 = _;
                                                                                                  //do stuff with level3
                                                                                                  }


                                                                                                  //or you can indent:
                                                                                                  if (_=_.level1)
                                                                                                  if (_=_.level2)
                                                                                                  if (_=_.level3) {

                                                                                                  let level3 = _;
                                                                                                  //do stuff with level3
                                                                                                  }





                                                                                                  //you could also use 'stacked' if statements. This helps if your object goes very deep. 
                                                                                                  //(formatted without nesting or curly braces except the last one)

                                                                                                  let _ = test;

                                                                                                  if (_=_.level1)
                                                                                                  if (_=_.level2)
                                                                                                  if (_=_.level3) {

                                                                                                  let level3 = _;
                                                                                                  //do stuff with level3
                                                                                                  }


                                                                                                  //or you can indent:
                                                                                                  if (_=_.level1)
                                                                                                  if (_=_.level2)
                                                                                                  if (_=_.level3) {

                                                                                                  let level3 = _;
                                                                                                  //do stuff with level3
                                                                                                  }






                                                                                                  share|improve this answer














                                                                                                  share|improve this answer



                                                                                                  share|improve this answer








                                                                                                  edited Aug 11 '17 at 22:10

























                                                                                                  answered Jul 26 '17 at 0:19









                                                                                                  kubakoz

                                                                                                  363




                                                                                                  363






















                                                                                                      up vote
                                                                                                      1
                                                                                                      down vote













                                                                                                      theres a function here on thecodeabode (safeRead) which will do this in a safe manner... i.e.



                                                                                                      safeRead(test, 'level1', 'level2', 'level3');


                                                                                                      if any property is null or undefined, an empty string is returned






                                                                                                      share|improve this answer





















                                                                                                      • I kind of like this method with templating because it returns an empty string if not set
                                                                                                        – Lounge9
                                                                                                        Jan 21 '16 at 19:26















                                                                                                      up vote
                                                                                                      1
                                                                                                      down vote













                                                                                                      theres a function here on thecodeabode (safeRead) which will do this in a safe manner... i.e.



                                                                                                      safeRead(test, 'level1', 'level2', 'level3');


                                                                                                      if any property is null or undefined, an empty string is returned






                                                                                                      share|improve this answer





















                                                                                                      • I kind of like this method with templating because it returns an empty string if not set
                                                                                                        – Lounge9
                                                                                                        Jan 21 '16 at 19:26













                                                                                                      up vote
                                                                                                      1
                                                                                                      down vote










                                                                                                      up vote
                                                                                                      1
                                                                                                      down vote









                                                                                                      theres a function here on thecodeabode (safeRead) which will do this in a safe manner... i.e.



                                                                                                      safeRead(test, 'level1', 'level2', 'level3');


                                                                                                      if any property is null or undefined, an empty string is returned






                                                                                                      share|improve this answer












                                                                                                      theres a function here on thecodeabode (safeRead) which will do this in a safe manner... i.e.



                                                                                                      safeRead(test, 'level1', 'level2', 'level3');


                                                                                                      if any property is null or undefined, an empty string is returned







                                                                                                      share|improve this answer












                                                                                                      share|improve this answer



                                                                                                      share|improve this answer










                                                                                                      answered Apr 13 '13 at 8:50









                                                                                                      Ben

                                                                                                      1,055118




                                                                                                      1,055118












                                                                                                      • I kind of like this method with templating because it returns an empty string if not set
                                                                                                        – Lounge9
                                                                                                        Jan 21 '16 at 19:26


















                                                                                                      • I kind of like this method with templating because it returns an empty string if not set
                                                                                                        – Lounge9
                                                                                                        Jan 21 '16 at 19:26
















                                                                                                      I kind of like this method with templating because it returns an empty string if not set
                                                                                                      – Lounge9
                                                                                                      Jan 21 '16 at 19:26




                                                                                                      I kind of like this method with templating because it returns an empty string if not set
                                                                                                      – Lounge9
                                                                                                      Jan 21 '16 at 19:26










                                                                                                      up vote
                                                                                                      1
                                                                                                      down vote













                                                                                                      Based on a previous comment, here is another version where the main object could not be defined either:



                                                                                                      // Supposing that our property is at first.second.third.property:
                                                                                                      var property = (((typeof first !== 'undefined' ? first : {}).second || {}).third || {}).property;





                                                                                                      share|improve this answer



























                                                                                                        up vote
                                                                                                        1
                                                                                                        down vote













                                                                                                        Based on a previous comment, here is another version where the main object could not be defined either:



                                                                                                        // Supposing that our property is at first.second.third.property:
                                                                                                        var property = (((typeof first !== 'undefined' ? first : {}).second || {}).third || {}).property;





                                                                                                        share|improve this answer

























                                                                                                          up vote
                                                                                                          1
                                                                                                          down vote










                                                                                                          up vote
                                                                                                          1
                                                                                                          down vote









                                                                                                          Based on a previous comment, here is another version where the main object could not be defined either:



                                                                                                          // Supposing that our property is at first.second.third.property:
                                                                                                          var property = (((typeof first !== 'undefined' ? first : {}).second || {}).third || {}).property;





                                                                                                          share|improve this answer














                                                                                                          Based on a previous comment, here is another version where the main object could not be defined either:



                                                                                                          // Supposing that our property is at first.second.third.property:
                                                                                                          var property = (((typeof first !== 'undefined' ? first : {}).second || {}).third || {}).property;






                                                                                                          share|improve this answer














                                                                                                          share|improve this answer



                                                                                                          share|improve this answer








                                                                                                          edited May 23 '17 at 12:34









                                                                                                          Community

                                                                                                          11




                                                                                                          11










                                                                                                          answered Aug 27 '13 at 21:09









                                                                                                          Juampy NR

                                                                                                          1,6701613




                                                                                                          1,6701613






















                                                                                                              up vote
                                                                                                              1
                                                                                                              down vote













                                                                                                              I wrote my own function that takes the desired path, and has a good and bad callback function.



                                                                                                              function checkForPathInObject(object, path, callbackGood, callbackBad){
                                                                                                              var pathParts = path.split(".");
                                                                                                              var currentObjectPath = object;

                                                                                                              // Test every step to see if it exists in object
                                                                                                              for(var i=0; i<(pathParts.length); i++){
                                                                                                              var currentPathPart = pathParts[i];
                                                                                                              if(!currentObjectPath.hasOwnProperty(pathParts[i])){
                                                                                                              if(callbackBad){
                                                                                                              callbackBad();
                                                                                                              }
                                                                                                              return false;
                                                                                                              } else {
                                                                                                              currentObjectPath = currentObjectPath[pathParts[i]];
                                                                                                              }
                                                                                                              }

                                                                                                              // call full path in callback
                                                                                                              callbackGood();
                                                                                                              }


                                                                                                              Usage:



                                                                                                              var testObject = {
                                                                                                              level1:{
                                                                                                              level2:{
                                                                                                              level3:{
                                                                                                              }
                                                                                                              }
                                                                                                              }
                                                                                                              };


                                                                                                              checkForPathInObject(testObject, "level1.level2.level3", function(){alert("good!")}, function(){alert("bad!")}); // good

                                                                                                              checkForPathInObject(testObject, "level1.level2.level3.levelNotThere", function(){alert("good!")}, function(){alert("bad!")}); //bad





                                                                                                              share|improve this answer





















                                                                                                              • I though fair to give you credit for the inspiration to adapt your code to my answer
                                                                                                                – davewoodhall
                                                                                                                Jun 2 '16 at 20:02

















                                                                                                              up vote
                                                                                                              1
                                                                                                              down vote













                                                                                                              I wrote my own function that takes the desired path, and has a good and bad callback function.



                                                                                                              function checkForPathInObject(object, path, callbackGood, callbackBad){
                                                                                                              var pathParts = path.split(".");
                                                                                                              var currentObjectPath = object;

                                                                                                              // Test every step to see if it exists in object
                                                                                                              for(var i=0; i<(pathParts.length); i++){
                                                                                                              var currentPathPart = pathParts[i];
                                                                                                              if(!currentObjectPath.hasOwnProperty(pathParts[i])){
                                                                                                              if(callbackBad){
                                                                                                              callbackBad();
                                                                                                              }
                                                                                                              return false;
                                                                                                              } else {
                                                                                                              currentObjectPath = currentObjectPath[pathParts[i]];
                                                                                                              }
                                                                                                              }

                                                                                                              // call full path in callback
                                                                                                              callbackGood();
                                                                                                              }


                                                                                                              Usage:



                                                                                                              var testObject = {
                                                                                                              level1:{
                                                                                                              level2:{
                                                                                                              level3:{
                                                                                                              }
                                                                                                              }
                                                                                                              }
                                                                                                              };


                                                                                                              checkForPathInObject(testObject, "level1.level2.level3", function(){alert("good!")}, function(){alert("bad!")}); // good

                                                                                                              checkForPathInObject(testObject, "level1.level2.level3.levelNotThere", function(){alert("good!")}, function(){alert("bad!")}); //bad





                                                                                                              share|improve this answer





















                                                                                                              • I though fair to give you credit for the inspiration to adapt your code to my answer
                                                                                                                – davewoodhall
                                                                                                                Jun 2 '16 at 20:02















                                                                                                              up vote
                                                                                                              1
                                                                                                              down vote










                                                                                                              up vote
                                                                                                              1
                                                                                                              down vote









                                                                                                              I wrote my own function that takes the desired path, and has a good and bad callback function.



                                                                                                              function checkForPathInObject(object, path, callbackGood, callbackBad){
                                                                                                              var pathParts = path.split(".");
                                                                                                              var currentObjectPath = object;

                                                                                                              // Test every step to see if it exists in object
                                                                                                              for(var i=0; i<(pathParts.length); i++){
                                                                                                              var currentPathPart = pathParts[i];
                                                                                                              if(!currentObjectPath.hasOwnProperty(pathParts[i])){
                                                                                                              if(callbackBad){
                                                                                                              callbackBad();
                                                                                                              }
                                                                                                              return false;
                                                                                                              } else {
                                                                                                              currentObjectPath = currentObjectPath[pathParts[i]];
                                                                                                              }
                                                                                                              }

                                                                                                              // call full path in callback
                                                                                                              callbackGood();
                                                                                                              }


                                                                                                              Usage:



                                                                                                              var testObject = {
                                                                                                              level1:{
                                                                                                              level2:{
                                                                                                              level3:{
                                                                                                              }
                                                                                                              }
                                                                                                              }
                                                                                                              };


                                                                                                              checkForPathInObject(testObject, "level1.level2.level3", function(){alert("good!")}, function(){alert("bad!")}); // good

                                                                                                              checkForPathInObject(testObject, "level1.level2.level3.levelNotThere", function(){alert("good!")}, function(){alert("bad!")}); //bad





                                                                                                              share|improve this answer












                                                                                                              I wrote my own function that takes the desired path, and has a good and bad callback function.



                                                                                                              function checkForPathInObject(object, path, callbackGood, callbackBad){
                                                                                                              var pathParts = path.split(".");
                                                                                                              var currentObjectPath = object;

                                                                                                              // Test every step to see if it exists in object
                                                                                                              for(var i=0; i<(pathParts.length); i++){
                                                                                                              var currentPathPart = pathParts[i];
                                                                                                              if(!currentObjectPath.hasOwnProperty(pathParts[i])){
                                                                                                              if(callbackBad){
                                                                                                              callbackBad();
                                                                                                              }
                                                                                                              return false;
                                                                                                              } else {
                                                                                                              currentObjectPath = currentObjectPath[pathParts[i]];
                                                                                                              }
                                                                                                              }

                                                                                                              // call full path in callback
                                                                                                              callbackGood();
                                                                                                              }


                                                                                                              Usage:



                                                                                                              var testObject = {
                                                                                                              level1:{
                                                                                                              level2:{
                                                                                                              level3:{
                                                                                                              }
                                                                                                              }
                                                                                                              }
                                                                                                              };


                                                                                                              checkForPathInObject(testObject, "level1.level2.level3", function(){alert("good!")}, function(){alert("bad!")}); // good

                                                                                                              checkForPathInObject(testObject, "level1.level2.level3.levelNotThere", function(){alert("good!")}, function(){alert("bad!")}); //bad






                                                                                                              share|improve this answer












                                                                                                              share|improve this answer



                                                                                                              share|improve this answer










                                                                                                              answered Mar 19 '15 at 17:55









                                                                                                              Stephane LaFlèche

                                                                                                              111




                                                                                                              111












                                                                                                              • I though fair to give you credit for the inspiration to adapt your code to my answer
                                                                                                                – davewoodhall
                                                                                                                Jun 2 '16 at 20:02




















                                                                                                              • I though fair to give you credit for the inspiration to adapt your code to my answer
                                                                                                                – davewoodhall
                                                                                                                Jun 2 '16 at 20:02


















                                                                                                              I though fair to give you credit for the inspiration to adapt your code to my answer
                                                                                                              – davewoodhall
                                                                                                              Jun 2 '16 at 20:02






                                                                                                              I though fair to give you credit for the inspiration to adapt your code to my answer
                                                                                                              – davewoodhall
                                                                                                              Jun 2 '16 at 20:02












                                                                                                              up vote
                                                                                                              1
                                                                                                              down vote













                                                                                                              //Just in case is not supported or not included by your framework
                                                                                                              //***************************************************
                                                                                                              Array.prototype.some = function(fn, thisObj) {
                                                                                                              var scope = thisObj || window;
                                                                                                              for ( var i=0, j=this.length; i < j; ++i ) {
                                                                                                              if ( fn.call(scope, this[i], i, this) ) {
                                                                                                              return true;
                                                                                                              }
                                                                                                              }
                                                                                                              return false;
                                                                                                              };
                                                                                                              //****************************************************

                                                                                                              function isSet (object, string) {
                                                                                                              if (!object) return false;
                                                                                                              var childs = string.split('.');
                                                                                                              if (childs.length > 0 ) {
                                                                                                              return !childs.some(function (item) {
                                                                                                              if (item in object) {
                                                                                                              object = object[item];
                                                                                                              return false;
                                                                                                              } else return true;
                                                                                                              });
                                                                                                              } else if (string in object) {
                                                                                                              return true;
                                                                                                              } else return false;
                                                                                                              }

                                                                                                              var object = {
                                                                                                              data: {
                                                                                                              item: {
                                                                                                              sub_item: {
                                                                                                              bla: {
                                                                                                              here : {
                                                                                                              iam: true
                                                                                                              }
                                                                                                              }
                                                                                                              }
                                                                                                              }
                                                                                                              }
                                                                                                              };

                                                                                                              console.log(isSet(object,'data.item')); // true
                                                                                                              console.log(isSet(object,'x')); // false
                                                                                                              console.log(isSet(object,'data.sub_item')); // false
                                                                                                              console.log(isSet(object,'data.item')); // true
                                                                                                              console.log(isSet(object,'data.item.sub_item.bla.here.iam')); // true





                                                                                                              share|improve this answer

























                                                                                                                up vote
                                                                                                                1
                                                                                                                down vote













                                                                                                                //Just in case is not supported or not included by your framework
                                                                                                                //***************************************************
                                                                                                                Array.prototype.some = function(fn, thisObj) {
                                                                                                                var scope = thisObj || window;
                                                                                                                for ( var i=0, j=this.length; i < j; ++i ) {
                                                                                                                if ( fn.call(scope, this[i], i, this) ) {
                                                                                                                return true;
                                                                                                                }
                                                                                                                }
                                                                                                                return false;
                                                                                                                };
                                                                                                                //****************************************************

                                                                                                                function isSet (object, string) {
                                                                                                                if (!object) return false;
                                                                                                                var childs = string.split('.');
                                                                                                                if (childs.length > 0 ) {
                                                                                                                return !childs.some(function (item) {
                                                                                                                if (item in object) {
                                                                                                                object = object[item];
                                                                                                                return false;
                                                                                                                } else return true;
                                                                                                                });
                                                                                                                } else if (string in object) {
                                                                                                                return true;
                                                                                                                } else return false;
                                                                                                                }

                                                                                                                var object = {
                                                                                                                data: {
                                                                                                                item: {
                                                                                                                sub_item: {
                                                                                                                bla: {
                                                                                                                here : {
                                                                                                                iam: true
                                                                                                                }
                                                                                                                }
                                                                                                                }
                                                                                                                }
                                                                                                                }
                                                                                                                };

                                                                                                                console.log(isSet(object,'data.item')); // true
                                                                                                                console.log(isSet(object,'x')); // false
                                                                                                                console.log(isSet(object,'data.sub_item')); // false
                                                                                                                console.log(isSet(object,'data.item')); // true
                                                                                                                console.log(isSet(object,'data.item.sub_item.bla.here.iam')); // true





                                                                                                                share|improve this answer























                                                                                                                  up vote
                                                                                                                  1
                                                                                                                  down vote










                                                                                                                  up vote
                                                                                                                  1
                                                                                                                  down vote









                                                                                                                  //Just in case is not supported or not included by your framework
                                                                                                                  //***************************************************
                                                                                                                  Array.prototype.some = function(fn, thisObj) {
                                                                                                                  var scope = thisObj || window;
                                                                                                                  for ( var i=0, j=this.length; i < j; ++i ) {
                                                                                                                  if ( fn.call(scope, this[i], i, this) ) {
                                                                                                                  return true;
                                                                                                                  }
                                                                                                                  }
                                                                                                                  return false;
                                                                                                                  };
                                                                                                                  //****************************************************

                                                                                                                  function isSet (object, string) {
                                                                                                                  if (!object) return false;
                                                                                                                  var childs = string.split('.');
                                                                                                                  if (childs.length > 0 ) {
                                                                                                                  return !childs.some(function (item) {
                                                                                                                  if (item in object) {
                                                                                                                  object = object[item];
                                                                                                                  return false;
                                                                                                                  } else return true;
                                                                                                                  });
                                                                                                                  } else if (string in object) {
                                                                                                                  return true;
                                                                                                                  } else return false;
                                                                                                                  }

                                                                                                                  var object = {
                                                                                                                  data: {
                                                                                                                  item: {
                                                                                                                  sub_item: {
                                                                                                                  bla: {
                                                                                                                  here : {
                                                                                                                  iam: true
                                                                                                                  }
                                                                                                                  }
                                                                                                                  }
                                                                                                                  }
                                                                                                                  }
                                                                                                                  };

                                                                                                                  console.log(isSet(object,'data.item')); // true
                                                                                                                  console.log(isSet(object,'x')); // false
                                                                                                                  console.log(isSet(object,'data.sub_item')); // false
                                                                                                                  console.log(isSet(object,'data.item')); // true
                                                                                                                  console.log(isSet(object,'data.item.sub_item.bla.here.iam')); // true





                                                                                                                  share|improve this answer












                                                                                                                  //Just in case is not supported or not included by your framework
                                                                                                                  //***************************************************
                                                                                                                  Array.prototype.some = function(fn, thisObj) {
                                                                                                                  var scope = thisObj || window;
                                                                                                                  for ( var i=0, j=this.length; i < j; ++i ) {
                                                                                                                  if ( fn.call(scope, this[i], i, this) ) {
                                                                                                                  return true;
                                                                                                                  }
                                                                                                                  }
                                                                                                                  return false;
                                                                                                                  };
                                                                                                                  //****************************************************

                                                                                                                  function isSet (object, string) {
                                                                                                                  if (!object) return false;
                                                                                                                  var childs = string.split('.');
                                                                                                                  if (childs.length > 0 ) {
                                                                                                                  return !childs.some(function (item) {
                                                                                                                  if (item in object) {
                                                                                                                  object = object[item];
                                                                                                                  return false;
                                                                                                                  } else return true;
                                                                                                                  });
                                                                                                                  } else if (string in object) {
                                                                                                                  return true;
                                                                                                                  } else return false;
                                                                                                                  }

                                                                                                                  var object = {
                                                                                                                  data: {
                                                                                                                  item: {
                                                                                                                  sub_item: {
                                                                                                                  bla: {
                                                                                                                  here : {
                                                                                                                  iam: true
                                                                                                                  }
                                                                                                                  }
                                                                                                                  }
                                                                                                                  }
                                                                                                                  }
                                                                                                                  };

                                                                                                                  console.log(isSet(object,'data.item')); // true
                                                                                                                  console.log(isSet(object,'x')); // false
                                                                                                                  console.log(isSet(object,'data.sub_item')); // false
                                                                                                                  console.log(isSet(object,'data.item')); // true
                                                                                                                  console.log(isSet(object,'data.item.sub_item.bla.here.iam')); // true






                                                                                                                  share|improve this answer












                                                                                                                  share|improve this answer



                                                                                                                  share|improve this answer










                                                                                                                  answered Jul 10 '15 at 14:27









                                                                                                                  alejandro

                                                                                                                  2,16311320




                                                                                                                  2,16311320






















                                                                                                                      up vote
                                                                                                                      1
                                                                                                                      down vote













                                                                                                                      I was looking for the value to be returned if the property exists, so I modified the answer by CMS above. Here's what I came up with:






                                                                                                                      function getNestedProperty(obj, key) {
                                                                                                                      // Get property array from key string
                                                                                                                      var properties = key.split(".");

                                                                                                                      // Iterate through properties, returning undefined if object is null or property doesn't exist
                                                                                                                      for (var i = 0; i < properties.length; i++) {
                                                                                                                      if (!obj || !obj.hasOwnProperty(properties[i])) {
                                                                                                                      return;
                                                                                                                      }
                                                                                                                      obj = obj[properties[i]];
                                                                                                                      }

                                                                                                                      // Nested property found, so return the value
                                                                                                                      return obj;
                                                                                                                      }


                                                                                                                      Usage:

                                                                                                                      getNestedProperty(test, "level1.level2.level3") // "level3"
                                                                                                                      getNestedProperty(test, "level1.level2.foo") // undefined








                                                                                                                      share|improve this answer

























                                                                                                                        up vote
                                                                                                                        1
                                                                                                                        down vote













                                                                                                                        I was looking for the value to be returned if the property exists, so I modified the answer by CMS above. Here's what I came up with:






                                                                                                                        function getNestedProperty(obj, key) {
                                                                                                                        // Get property array from key string
                                                                                                                        var properties = key.split(".");

                                                                                                                        // Iterate through properties, returning undefined if object is null or property doesn't exist
                                                                                                                        for (var i = 0; i < properties.length; i++) {
                                                                                                                        if (!obj || !obj.hasOwnProperty(properties[i])) {
                                                                                                                        return;
                                                                                                                        }
                                                                                                                        obj = obj[properties[i]];
                                                                                                                        }

                                                                                                                        // Nested property found, so return the value
                                                                                                                        return obj;
                                                                                                                        }


                                                                                                                        Usage:

                                                                                                                        getNestedProperty(test, "level1.level2.level3") // "level3"
                                                                                                                        getNestedProperty(test, "level1.level2.foo") // undefined








                                                                                                                        share|improve this answer























                                                                                                                          up vote
                                                                                                                          1
                                                                                                                          down vote










                                                                                                                          up vote
                                                                                                                          1
                                                                                                                          down vote









                                                                                                                          I was looking for the value to be returned if the property exists, so I modified the answer by CMS above. Here's what I came up with:






                                                                                                                          function getNestedProperty(obj, key) {
                                                                                                                          // Get property array from key string
                                                                                                                          var properties = key.split(".");

                                                                                                                          // Iterate through properties, returning undefined if object is null or property doesn't exist
                                                                                                                          for (var i = 0; i < properties.length; i++) {
                                                                                                                          if (!obj || !obj.hasOwnProperty(properties[i])) {
                                                                                                                          return;
                                                                                                                          }
                                                                                                                          obj = obj[properties[i]];
                                                                                                                          }

                                                                                                                          // Nested property found, so return the value
                                                                                                                          return obj;
                                                                                                                          }


                                                                                                                          Usage:

                                                                                                                          getNestedProperty(test, "level1.level2.level3") // "level3"
                                                                                                                          getNestedProperty(test, "level1.level2.foo") // undefined








                                                                                                                          share|improve this answer












                                                                                                                          I was looking for the value to be returned if the property exists, so I modified the answer by CMS above. Here's what I came up with:






                                                                                                                          function getNestedProperty(obj, key) {
                                                                                                                          // Get property array from key string
                                                                                                                          var properties = key.split(".");

                                                                                                                          // Iterate through properties, returning undefined if object is null or property doesn't exist
                                                                                                                          for (var i = 0; i < properties.length; i++) {
                                                                                                                          if (!obj || !obj.hasOwnProperty(properties[i])) {
                                                                                                                          return;
                                                                                                                          }
                                                                                                                          obj = obj[properties[i]];
                                                                                                                          }

                                                                                                                          // Nested property found, so return the value
                                                                                                                          return obj;
                                                                                                                          }


                                                                                                                          Usage:

                                                                                                                          getNestedProperty(test, "level1.level2.level3") // "level3"
                                                                                                                          getNestedProperty(test, "level1.level2.foo") // undefined








                                                                                                                          function getNestedProperty(obj, key) {
                                                                                                                          // Get property array from key string
                                                                                                                          var properties = key.split(".");

                                                                                                                          // Iterate through properties, returning undefined if object is null or property doesn't exist
                                                                                                                          for (var i = 0; i < properties.length; i++) {
                                                                                                                          if (!obj || !obj.hasOwnProperty(properties[i])) {
                                                                                                                          return;
                                                                                                                          }
                                                                                                                          obj = obj[properties[i]];
                                                                                                                          }

                                                                                                                          // Nested property found, so return the value
                                                                                                                          return obj;
                                                                                                                          }


                                                                                                                          Usage:

                                                                                                                          getNestedProperty(test, "level1.level2.level3") // "level3"
                                                                                                                          getNestedProperty(test, "level1.level2.foo") // undefined





                                                                                                                          function getNestedProperty(obj, key) {
                                                                                                                          // Get property array from key string
                                                                                                                          var properties = key.split(".");

                                                                                                                          // Iterate through properties, returning undefined if object is null or property doesn't exist
                                                                                                                          for (var i = 0; i < properties.length; i++) {
                                                                                                                          if (!obj || !obj.hasOwnProperty(properties[i])) {
                                                                                                                          return;
                                                                                                                          }
                                                                                                                          obj = obj[properties[i]];
                                                                                                                          }

                                                                                                                          // Nested property found, so return the value
                                                                                                                          return obj;
                                                                                                                          }


                                                                                                                          Usage:

                                                                                                                          getNestedProperty(test, "level1.level2.level3") // "level3"
                                                                                                                          getNestedProperty(test, "level1.level2.foo") // undefined






                                                                                                                          share|improve this answer












                                                                                                                          share|improve this answer



                                                                                                                          share|improve this answer










                                                                                                                          answered Jul 25 '15 at 3:13









                                                                                                                          Noah Stahl

                                                                                                                          9911711




                                                                                                                          9911711






















                                                                                                                              up vote
                                                                                                                              1
                                                                                                                              down vote













                                                                                                                              I was having the same issue and and wanted to see if I could come up with a my own solution. This accepts the path you want to check as a string.



                                                                                                                              function checkPathForTruthy(obj, path) {
                                                                                                                              if (/[[a-zA-Z_]/.test(path)) {
                                                                                                                              console.log("Cannot resolve variables in property accessors");
                                                                                                                              return false;
                                                                                                                              }

                                                                                                                              path = path.replace(/[/g, ".");
                                                                                                                              path = path.replace(/]|'|"/g, "");
                                                                                                                              path = path.split(".");

                                                                                                                              var steps = 0;
                                                                                                                              var lastRef = obj;
                                                                                                                              var exists = path.every(key => {
                                                                                                                              var currentItem = lastRef[path[steps]];
                                                                                                                              if (currentItem) {
                                                                                                                              lastRef = currentItem;
                                                                                                                              steps++;
                                                                                                                              return true;
                                                                                                                              } else {
                                                                                                                              return false;
                                                                                                                              }
                                                                                                                              });

                                                                                                                              return exists;
                                                                                                                              }


                                                                                                                              Here is a snippet with some logging and test cases:






                                                                                                                              console.clear();
                                                                                                                              var testCases = [
                                                                                                                              ["data.Messages[0].Code", true],
                                                                                                                              ["data.Messages[1].Code", true],
                                                                                                                              ["data.Messages[0]['Code']", true],
                                                                                                                              ['data.Messages[0]["Code"]', true],
                                                                                                                              ["data[Messages][0]['Code']", false],
                                                                                                                              ["data['Messages'][0]['Code']", true]
                                                                                                                              ];
                                                                                                                              var path = "data.Messages[0].Code";
                                                                                                                              var obj = {
                                                                                                                              data: {
                                                                                                                              Messages: [{
                                                                                                                              Code: "0"
                                                                                                                              }, {
                                                                                                                              Code: "1"
                                                                                                                              }]
                                                                                                                              }
                                                                                                                              }

                                                                                                                              function checkPathForTruthy(obj, path) {
                                                                                                                              if (/[[a-zA-Z_]/.test(path)) {
                                                                                                                              console.log("Cannot resolve variables in property accessors");
                                                                                                                              return false;
                                                                                                                              }

                                                                                                                              path = path.replace(/[/g, ".");
                                                                                                                              path = path.replace(/]|'|"/g, "");
                                                                                                                              path = path.split(".");

                                                                                                                              var steps = 0;
                                                                                                                              var lastRef = obj;
                                                                                                                              var logOutput = ;
                                                                                                                              var exists = path.every(key => {
                                                                                                                              var currentItem = lastRef[path[steps]];
                                                                                                                              if (currentItem) {
                                                                                                                              logOutput.push(currentItem);
                                                                                                                              lastRef = currentItem;
                                                                                                                              steps++;
                                                                                                                              return true;
                                                                                                                              } else {
                                                                                                                              return false;
                                                                                                                              }
                                                                                                                              });
                                                                                                                              console.log(exists, logOutput);
                                                                                                                              return exists;
                                                                                                                              }

                                                                                                                              testCases.forEach(testCase => {
                                                                                                                              if (checkPathForTruthy(obj, testCase[0]) === testCase[1]) {
                                                                                                                              console.log("Passed: " + testCase[0]);
                                                                                                                              } else {
                                                                                                                              console.log("Failed: " + testCase[0] + " expected " + testCase[1]);
                                                                                                                              }
                                                                                                                              });








                                                                                                                              share|improve this answer



























                                                                                                                                up vote
                                                                                                                                1
                                                                                                                                down vote













                                                                                                                                I was having the same issue and and wanted to see if I could come up with a my own solution. This accepts the path you want to check as a string.



                                                                                                                                function checkPathForTruthy(obj, path) {
                                                                                                                                if (/[[a-zA-Z_]/.test(path)) {
                                                                                                                                console.log("Cannot resolve variables in property accessors");
                                                                                                                                return false;
                                                                                                                                }

                                                                                                                                path = path.replace(/[/g, ".");
                                                                                                                                path = path.replace(/]|'|"/g, "");
                                                                                                                                path = path.split(".");

                                                                                                                                var steps = 0;
                                                                                                                                var lastRef = obj;
                                                                                                                                var exists = path.every(key => {
                                                                                                                                var currentItem = lastRef[path[steps]];
                                                                                                                                if (currentItem) {
                                                                                                                                lastRef = currentItem;
                                                                                                                                steps++;
                                                                                                                                return true;
                                                                                                                                } else {
                                                                                                                                return false;
                                                                                                                                }
                                                                                                                                });

                                                                                                                                return exists;
                                                                                                                                }


                                                                                                                                Here is a snippet with some logging and test cases:






                                                                                                                                console.clear();
                                                                                                                                var testCases = [
                                                                                                                                ["data.Messages[0].Code", true],
                                                                                                                                ["data.Messages[1].Code", true],
                                                                                                                                ["data.Messages[0]['Code']", true],
                                                                                                                                ['data.Messages[0]["Code"]', true],
                                                                                                                                ["data[Messages][0]['Code']", false],
                                                                                                                                ["data['Messages'][0]['Code']", true]
                                                                                                                                ];
                                                                                                                                var path = "data.Messages[0].Code";
                                                                                                                                var obj = {
                                                                                                                                data: {
                                                                                                                                Messages: [{
                                                                                                                                Code: "0"
                                                                                                                                }, {
                                                                                                                                Code: "1"
                                                                                                                                }]
                                                                                                                                }
                                                                                                                                }

                                                                                                                                function checkPathForTruthy(obj, path) {
                                                                                                                                if (/[[a-zA-Z_]/.test(path)) {
                                                                                                                                console.log("Cannot resolve variables in property accessors");
                                                                                                                                return false;
                                                                                                                                }

                                                                                                                                path = path.replace(/[/g, ".");
                                                                                                                                path = path.replace(/]|'|"/g, "");
                                                                                                                                path = path.split(".");

                                                                                                                                var steps = 0;
                                                                                                                                var lastRef = obj;
                                                                                                                                var logOutput = ;
                                                                                                                                var exists = path.every(key => {
                                                                                                                                var currentItem = lastRef[path[steps]];
                                                                                                                                if (currentItem) {
                                                                                                                                logOutput.push(currentItem);
                                                                                                                                lastRef = currentItem;
                                                                                                                                steps++;
                                                                                                                                return true;
                                                                                                                                } else {
                                                                                                                                return false;
                                                                                                                                }
                                                                                                                                });
                                                                                                                                console.log(exists, logOutput);
                                                                                                                                return exists;
                                                                                                                                }

                                                                                                                                testCases.forEach(testCase => {
                                                                                                                                if (checkPathForTruthy(obj, testCase[0]) === testCase[1]) {
                                                                                                                                console.log("Passed: " + testCase[0]);
                                                                                                                                } else {
                                                                                                                                console.log("Failed: " + testCase[0] + " expected " + testCase[1]);
                                                                                                                                }
                                                                                                                                });








                                                                                                                                share|improve this answer

























                                                                                                                                  up vote
                                                                                                                                  1
                                                                                                                                  down vote










                                                                                                                                  up vote
                                                                                                                                  1
                                                                                                                                  down vote









                                                                                                                                  I was having the same issue and and wanted to see if I could come up with a my own solution. This accepts the path you want to check as a string.



                                                                                                                                  function checkPathForTruthy(obj, path) {
                                                                                                                                  if (/[[a-zA-Z_]/.test(path)) {
                                                                                                                                  console.log("Cannot resolve variables in property accessors");
                                                                                                                                  return false;
                                                                                                                                  }

                                                                                                                                  path = path.replace(/[/g, ".");
                                                                                                                                  path = path.replace(/]|'|"/g, "");
                                                                                                                                  path = path.split(".");

                                                                                                                                  var steps = 0;
                                                                                                                                  var lastRef = obj;
                                                                                                                                  var exists = path.every(key => {
                                                                                                                                  var currentItem = lastRef[path[steps]];
                                                                                                                                  if (currentItem) {
                                                                                                                                  lastRef = currentItem;
                                                                                                                                  steps++;
                                                                                                                                  return true;
                                                                                                                                  } else {
                                                                                                                                  return false;
                                                                                                                                  }
                                                                                                                                  });

                                                                                                                                  return exists;
                                                                                                                                  }


                                                                                                                                  Here is a snippet with some logging and test cases:






                                                                                                                                  console.clear();
                                                                                                                                  var testCases = [
                                                                                                                                  ["data.Messages[0].Code", true],
                                                                                                                                  ["data.Messages[1].Code", true],
                                                                                                                                  ["data.Messages[0]['Code']", true],
                                                                                                                                  ['data.Messages[0]["Code"]', true],
                                                                                                                                  ["data[Messages][0]['Code']", false],
                                                                                                                                  ["data['Messages'][0]['Code']", true]
                                                                                                                                  ];
                                                                                                                                  var path = "data.Messages[0].Code";
                                                                                                                                  var obj = {
                                                                                                                                  data: {
                                                                                                                                  Messages: [{
                                                                                                                                  Code: "0"
                                                                                                                                  }, {
                                                                                                                                  Code: "1"
                                                                                                                                  }]
                                                                                                                                  }
                                                                                                                                  }

                                                                                                                                  function checkPathForTruthy(obj, path) {
                                                                                                                                  if (/[[a-zA-Z_]/.test(path)) {
                                                                                                                                  console.log("Cannot resolve variables in property accessors");
                                                                                                                                  return false;
                                                                                                                                  }

                                                                                                                                  path = path.replace(/[/g, ".");
                                                                                                                                  path = path.replace(/]|'|"/g, "");
                                                                                                                                  path = path.split(".");

                                                                                                                                  var steps = 0;
                                                                                                                                  var lastRef = obj;
                                                                                                                                  var logOutput = ;
                                                                                                                                  var exists = path.every(key => {
                                                                                                                                  var currentItem = lastRef[path[steps]];
                                                                                                                                  if (currentItem) {
                                                                                                                                  logOutput.push(currentItem);
                                                                                                                                  lastRef = currentItem;
                                                                                                                                  steps++;
                                                                                                                                  return true;
                                                                                                                                  } else {
                                                                                                                                  return false;
                                                                                                                                  }
                                                                                                                                  });
                                                                                                                                  console.log(exists, logOutput);
                                                                                                                                  return exists;
                                                                                                                                  }

                                                                                                                                  testCases.forEach(testCase => {
                                                                                                                                  if (checkPathForTruthy(obj, testCase[0]) === testCase[1]) {
                                                                                                                                  console.log("Passed: " + testCase[0]);
                                                                                                                                  } else {
                                                                                                                                  console.log("Failed: " + testCase[0] + " expected " + testCase[1]);
                                                                                                                                  }
                                                                                                                                  });








                                                                                                                                  share|improve this answer














                                                                                                                                  I was having the same issue and and wanted to see if I could come up with a my own solution. This accepts the path you want to check as a string.



                                                                                                                                  function checkPathForTruthy(obj, path) {
                                                                                                                                  if (/[[a-zA-Z_]/.test(path)) {
                                                                                                                                  console.log("Cannot resolve variables in property accessors");
                                                                                                                                  return false;
                                                                                                                                  }

                                                                                                                                  path = path.replace(/[/g, ".");
                                                                                                                                  path = path.replace(/]|'|"/g, "");
                                                                                                                                  path = path.split(".");

                                                                                                                                  var steps = 0;
                                                                                                                                  var lastRef = obj;
                                                                                                                                  var exists = path.every(key => {
                                                                                                                                  var currentItem = lastRef[path[steps]];
                                                                                                                                  if (currentItem) {
                                                                                                                                  lastRef = currentItem;
                                                                                                                                  steps++;
                                                                                                                                  return true;
                                                                                                                                  } else {
                                                                                                                                  return false;
                                                                                                                                  }
                                                                                                                                  });

                                                                                                                                  return exists;
                                                                                                                                  }


                                                                                                                                  Here is a snippet with some logging and test cases:






                                                                                                                                  console.clear();
                                                                                                                                  var testCases = [
                                                                                                                                  ["data.Messages[0].Code", true],
                                                                                                                                  ["data.Messages[1].Code", true],
                                                                                                                                  ["data.Messages[0]['Code']", true],
                                                                                                                                  ['data.Messages[0]["Code"]', true],
                                                                                                                                  ["data[Messages][0]['Code']", false],
                                                                                                                                  ["data['Messages'][0]['Code']", true]
                                                                                                                                  ];
                                                                                                                                  var path = "data.Messages[0].Code";
                                                                                                                                  var obj = {
                                                                                                                                  data: {
                                                                                                                                  Messages: [{
                                                                                                                                  Code: "0"
                                                                                                                                  }, {
                                                                                                                                  Code: "1"
                                                                                                                                  }]
                                                                                                                                  }
                                                                                                                                  }

                                                                                                                                  function checkPathForTruthy(obj, path) {
                                                                                                                                  if (/[[a-zA-Z_]/.test(path)) {
                                                                                                                                  console.log("Cannot resolve variables in property accessors");
                                                                                                                                  return false;
                                                                                                                                  }

                                                                                                                                  path = path.replace(/[/g, ".");
                                                                                                                                  path = path.replace(/]|'|"/g, "");
                                                                                                                                  path = path.split(".");

                                                                                                                                  var steps = 0;
                                                                                                                                  var lastRef = obj;
                                                                                                                                  var logOutput = ;
                                                                                                                                  var exists = path.every(key => {
                                                                                                                                  var currentItem = lastRef[path[steps]];
                                                                                                                                  if (currentItem) {
                                                                                                                                  logOutput.push(currentItem);
                                                                                                                                  lastRef = currentItem;
                                                                                                                                  steps++;
                                                                                                                                  return true;
                                                                                                                                  } else {
                                                                                                                                  return false;
                                                                                                                                  }
                                                                                                                                  });
                                                                                                                                  console.log(exists, logOutput);
                                                                                                                                  return exists;
                                                                                                                                  }

                                                                                                                                  testCases.forEach(testCase => {
                                                                                                                                  if (checkPathForTruthy(obj, testCase[0]) === testCase[1]) {
                                                                                                                                  console.log("Passed: " + testCase[0]);
                                                                                                                                  } else {
                                                                                                                                  console.log("Failed: " + testCase[0] + " expected " + testCase[1]);
                                                                                                                                  }
                                                                                                                                  });








                                                                                                                                  console.clear();
                                                                                                                                  var testCases = [
                                                                                                                                  ["data.Messages[0].Code", true],
                                                                                                                                  ["data.Messages[1].Code", true],
                                                                                                                                  ["data.Messages[0]['Code']", true],
                                                                                                                                  ['data.Messages[0]["Code"]', true],
                                                                                                                                  ["data[Messages][0]['Code']", false],
                                                                                                                                  ["data['Messages'][0]['Code']", true]
                                                                                                                                  ];
                                                                                                                                  var path = "data.Messages[0].Code";
                                                                                                                                  var obj = {
                                                                                                                                  data: {
                                                                                                                                  Messages: [{
                                                                                                                                  Code: "0"
                                                                                                                                  }, {
                                                                                                                                  Code: "1"
                                                                                                                                  }]
                                                                                                                                  }
                                                                                                                                  }

                                                                                                                                  function checkPathForTruthy(obj, path) {
                                                                                                                                  if (/[[a-zA-Z_]/.test(path)) {
                                                                                                                                  console.log("Cannot resolve variables in property accessors");
                                                                                                                                  return false;
                                                                                                                                  }

                                                                                                                                  path = path.replace(/[/g, ".");
                                                                                                                                  path = path.replace(/]|'|"/g, "");
                                                                                                                                  path = path.split(".");

                                                                                                                                  var steps = 0;
                                                                                                                                  var lastRef = obj;
                                                                                                                                  var logOutput = ;
                                                                                                                                  var exists = path.every(key => {
                                                                                                                                  var currentItem = lastRef[path[steps]];
                                                                                                                                  if (currentItem) {
                                                                                                                                  logOutput.push(currentItem);
                                                                                                                                  lastRef = currentItem;
                                                                                                                                  steps++;
                                                                                                                                  return true;
                                                                                                                                  } else {
                                                                                                                                  return false;
                                                                                                                                  }
                                                                                                                                  });
                                                                                                                                  console.log(exists, logOutput);
                                                                                                                                  return exists;
                                                                                                                                  }

                                                                                                                                  testCases.forEach(testCase => {
                                                                                                                                  if (checkPathForTruthy(obj, testCase[0]) === testCase[1]) {
                                                                                                                                  console.log("Passed: " + testCase[0]);
                                                                                                                                  } else {
                                                                                                                                  console.log("Failed: " + testCase[0] + " expected " + testCase[1]);
                                                                                                                                  }
                                                                                                                                  });





                                                                                                                                  console.clear();
                                                                                                                                  var testCases = [
                                                                                                                                  ["data.Messages[0].Code", true],
                                                                                                                                  ["data.Messages[1].Code", true],
                                                                                                                                  ["data.Messages[0]['Code']", true],
                                                                                                                                  ['data.Messages[0]["Code"]', true],
                                                                                                                                  ["data[Messages][0]['Code']", false],
                                                                                                                                  ["data['Messages'][0]['Code']", true]
                                                                                                                                  ];
                                                                                                                                  var path = "data.Messages[0].Code";
                                                                                                                                  var obj = {
                                                                                                                                  data: {
                                                                                                                                  Messages: [{
                                                                                                                                  Code: "0"
                                                                                                                                  }, {
                                                                                                                                  Code: "1"
                                                                                                                                  }]
                                                                                                                                  }
                                                                                                                                  }

                                                                                                                                  function checkPathForTruthy(obj, path) {
                                                                                                                                  if (/[[a-zA-Z_]/.test(path)) {
                                                                                                                                  console.log("Cannot resolve variables in property accessors");
                                                                                                                                  return false;
                                                                                                                                  }

                                                                                                                                  path = path.replace(/[/g, ".");
                                                                                                                                  path = path.replace(/]|'|"/g, "");
                                                                                                                                  path = path.split(".");

                                                                                                                                  var steps = 0;
                                                                                                                                  var lastRef = obj;
                                                                                                                                  var logOutput = ;
                                                                                                                                  var exists = path.every(key => {
                                                                                                                                  var currentItem = lastRef[path[steps]];
                                                                                                                                  if (currentItem) {
                                                                                                                                  logOutput.push(currentItem);
                                                                                                                                  lastRef = currentItem;
                                                                                                                                  steps++;
                                                                                                                                  return true;
                                                                                                                                  } else {
                                                                                                                                  return false;
                                                                                                                                  }
                                                                                                                                  });
                                                                                                                                  console.log(exists, logOutput);
                                                                                                                                  return exists;
                                                                                                                                  }

                                                                                                                                  testCases.forEach(testCase => {
                                                                                                                                  if (checkPathForTruthy(obj, testCase[0]) === testCase[1]) {
                                                                                                                                  console.log("Passed: " + testCase[0]);
                                                                                                                                  } else {
                                                                                                                                  console.log("Failed: " + testCase[0] + " expected " + testCase[1]);
                                                                                                                                  }
                                                                                                                                  });






                                                                                                                                  share|improve this answer














                                                                                                                                  share|improve this answer



                                                                                                                                  share|improve this answer








                                                                                                                                  edited Sep 14 '16 at 11:08

























                                                                                                                                  answered Sep 14 '16 at 9:50









                                                                                                                                  Jonathan

                                                                                                                                  5,17722154




                                                                                                                                  5,17722154






















                                                                                                                                      up vote
                                                                                                                                      1
                                                                                                                                      down vote













                                                                                                                                      Slight edit to this answer to allow nested arrays in the path






                                                                                                                                      var has = function (obj, key) {
                                                                                                                                      return key.split(".").every(function (x) {
                                                                                                                                      if (typeof obj != "object" || obj === null || !x in obj)
                                                                                                                                      return false;
                                                                                                                                      if (obj.constructor === Array)
                                                                                                                                      obj = obj[0];
                                                                                                                                      obj = obj[x];
                                                                                                                                      return true;
                                                                                                                                      });
                                                                                                                                      }





                                                                                                                                      Check linked answer for usages :)






                                                                                                                                      share|improve this answer

























                                                                                                                                        up vote
                                                                                                                                        1
                                                                                                                                        down vote













                                                                                                                                        Slight edit to this answer to allow nested arrays in the path






                                                                                                                                        var has = function (obj, key) {
                                                                                                                                        return key.split(".").every(function (x) {
                                                                                                                                        if (typeof obj != "object" || obj === null || !x in obj)
                                                                                                                                        return false;
                                                                                                                                        if (obj.constructor === Array)
                                                                                                                                        obj = obj[0];
                                                                                                                                        obj = obj[x];
                                                                                                                                        return true;
                                                                                                                                        });
                                                                                                                                        }





                                                                                                                                        Check linked answer for usages :)






                                                                                                                                        share|improve this answer























                                                                                                                                          up vote
                                                                                                                                          1
                                                                                                                                          down vote










                                                                                                                                          up vote
                                                                                                                                          1
                                                                                                                                          down vote









                                                                                                                                          Slight edit to this answer to allow nested arrays in the path






                                                                                                                                          var has = function (obj, key) {
                                                                                                                                          return key.split(".").every(function (x) {
                                                                                                                                          if (typeof obj != "object" || obj === null || !x in obj)
                                                                                                                                          return false;
                                                                                                                                          if (obj.constructor === Array)
                                                                                                                                          obj = obj[0];
                                                                                                                                          obj = obj[x];
                                                                                                                                          return true;
                                                                                                                                          });
                                                                                                                                          }





                                                                                                                                          Check linked answer for usages :)






                                                                                                                                          share|improve this answer












                                                                                                                                          Slight edit to this answer to allow nested arrays in the path






                                                                                                                                          var has = function (obj, key) {
                                                                                                                                          return key.split(".").every(function (x) {
                                                                                                                                          if (typeof obj != "object" || obj === null || !x in obj)
                                                                                                                                          return false;
                                                                                                                                          if (obj.constructor === Array)
                                                                                                                                          obj = obj[0];
                                                                                                                                          obj = obj[x];
                                                                                                                                          return true;
                                                                                                                                          });
                                                                                                                                          }





                                                                                                                                          Check linked answer for usages :)






                                                                                                                                          var has = function (obj, key) {
                                                                                                                                          return key.split(".").every(function (x) {
                                                                                                                                          if (typeof obj != "object" || obj === null || !x in obj)
                                                                                                                                          return false;
                                                                                                                                          if (obj.constructor === Array)
                                                                                                                                          obj = obj[0];
                                                                                                                                          obj = obj[x];
                                                                                                                                          return true;
                                                                                                                                          });
                                                                                                                                          }





                                                                                                                                          var has = function (obj, key) {
                                                                                                                                          return key.split(".").every(function (x) {
                                                                                                                                          if (typeof obj != "object" || obj === null || !x in obj)
                                                                                                                                          return false;
                                                                                                                                          if (obj.constructor === Array)
                                                                                                                                          obj = obj[0];
                                                                                                                                          obj = obj[x];
                                                                                                                                          return true;
                                                                                                                                          });
                                                                                                                                          }






                                                                                                                                          share|improve this answer












                                                                                                                                          share|improve this answer



                                                                                                                                          share|improve this answer










                                                                                                                                          answered Jun 22 '17 at 2:16









                                                                                                                                          wesley chase

                                                                                                                                          112




                                                                                                                                          112






















                                                                                                                                              1 2
                                                                                                                                              next

















                                                                                                                                              draft saved

                                                                                                                                              draft discarded




















































                                                                                                                                              Thanks for contributing an answer to Stack Overflow!


                                                                                                                                              • Please be sure to answer the question. Provide details and share your research!

                                                                                                                                              But avoid



                                                                                                                                              • Asking for help, clarification, or responding to other answers.

                                                                                                                                              • Making statements based on opinion; back them up with references or personal experience.


                                                                                                                                              To learn more, see our tips on writing great answers.





                                                                                                                                              Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                                                                                                                                              Please pay close attention to the following guidance:


                                                                                                                                              • Please be sure to answer the question. Provide details and share your research!

                                                                                                                                              But avoid



                                                                                                                                              • Asking for help, clarification, or responding to other answers.

                                                                                                                                              • Making statements based on opinion; back them up with references or personal experience.


                                                                                                                                              To learn more, see our tips on writing great answers.




                                                                                                                                              draft saved


                                                                                                                                              draft discarded














                                                                                                                                              StackExchange.ready(
                                                                                                                                              function () {
                                                                                                                                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f2631001%2ftest-for-existence-of-nested-javascript-object-key%23new-answer', 'question_page');
                                                                                                                                              }
                                                                                                                                              );

                                                                                                                                              Post as a guest















                                                                                                                                              Required, but never shown





















































                                                                                                                                              Required, but never shown














                                                                                                                                              Required, but never shown












                                                                                                                                              Required, but never shown







                                                                                                                                              Required, but never shown

































                                                                                                                                              Required, but never shown














                                                                                                                                              Required, but never shown












                                                                                                                                              Required, but never shown







                                                                                                                                              Required, but never shown











                                                                                                                                              Popular posts from this blog

                                                                                                                                              404 Error Contact Form 7 ajax form submitting

                                                                                                                                              How to know if a Active Directory user can login interactively

                                                                                                                                              TypeError: fit_transform() missing 1 required positional argument: 'X'