Test if a key exists anywhere in a nested object I have complex objects containing nested objects. I need to check if a key exists anywhere in the nested object. I wrote this code as a makeshift solution. Is there any other way to search for the key?

function checkKey(obj, key) {
    if(key in obj){
        return obj[key];
    }
    else{
        for (k in obj){
            t = obj[k]
            if(typeof t === "object" &amp;&amp; !Array.isArray(t) &amp;&amp; t !== null){
                return checkKey(t, key);    
            }
        }
    }
    return false
}


Test object:

obj = {
    "l1":"test333",
    "some":{
        "l2":"test2",
        "l22":"test3",
        "other":{
            "l3":["yellow"]
        }
    }
}


Search: checkKey(obj, "l3"); returns ["yellow"]
Your code has a couple of problems:

Semantic

You are using the construction key in obj, without checking if key is an actual property of obj. If obj is not an Object, but instead something resembling a class:

var PolarBear = function() {
  this.cuddly = true;
}

PolarBear.prototype.growl = function() {
  //nothing
}


Passing an instance of PolarBear to your function will return a function reference whenever you check if "growl" is a key. You could change this behaviour by checking if obj.isOwnProperty( key ) is true, or checking if obj is an Object.

Logic errors

Early return

If a key is an Array, and that array does not contain your key, your code will return anyway, even though you have not checked every key yet.

An example would be key "c" in the following Object. It is there, but your code would return false instead of 2, because the Object under key "a" does not contain a key "c".

{
  "a" : {
    "b" : 1
  }
  "c" : 2
}


Not exact key

Your code does not check if the key requested is the actual key we get. Some keys are transformed to an actual key. For example:

{
  "" : 1,
  "null" : 2,
  "false" : 3
}


Obviously, "" in obj would return true, but so would [] in obj, or null in obj, or false in obj, even though strictly speaking there is no key with that name. You could instead do Object.keys( obj ).indexOf( key ) &gt; -1.

Not returning key of Object under Array

You are silently ignoring Arrays. I suspect you do this because you do not want to return keys in Arrays, but this also means that if you have an Object inside your Array, you'll silently ignore this. For example, the key "c" in the following Object will be ignored, and thus false will be returned

{
  "a" : [
    { "b" : 1 },
    { "c" : 2 }
  ]
}