rox
rox

Reputation: 565

Is there an easier way to check existence of properties?

I have a object for example:

var extra = {
  field1: {
    foo: {},
    bar: {}
  }
}

field1 is not guaranteed to be set, If I need to check the existence of extra.field1.foo, I have to use:

if(typeof extra.field1 != 'undefined') {
    if(typeof extra.field1.foo != 'undefined') {
        ....
    }
}

Is there any simpler way to do the check?

Upvotes: 2

Views: 94

Answers (7)

Marc Compte
Marc Compte

Reputation: 4819

You could create a function that takes an array (or a string) and checks for each element in it, then you can check the existence of every nested property with only one conditional in your code.

obj1 = {
    field1: {
    col1: 1,
    col2: 'a'
  }
};
function checkExistence(arr) {
  // if arr is a string convert it into an array before checking it
  if (typeof arr == 'string') {
    arr=arr.split('.');
  }
  checked = arr[0]; i = 1;
  checks = window.hasOwnProperty(checked);
  while (checks && i < arr.length) {
    checked+='.'+arr[i];
    checks = typeof eval(checked) != 'undefined';
    ++i;
  }
  if (!checks) console.log(checked+' is undefined');
  else console.log(checked+' is defined');
  return checks;
}
checkExistence(['obj1','field1','col1']);
// obj1.field1.col1 is defined
checkExistence(['obj1','field1','col3']);
// obj1.field1.col3 is undefined
checkExistence(['obj1','field2','col3']);
// obj1.field2 is undefined
checkExistence(['obj2','field2','col3']);
// obj2 is undefined
checkExistence('obj1.field1.col1');
// obj1.field1.col1 is defined

...

if (checkExistence('obj1.field2.value1')) {
    // do something
}

Upvotes: 1

Morteza Tourani
Morteza Tourani

Reputation: 3536

This method can check any depth with no limit.

function exists(node, chainString) {
  return chainString.split('.')
    .every(prop => node && prop in node ? (node = node[prop]) || true : false);
}

nodes = [
  {x: { y: { z: 43 }}},
  {x: { y: { z: undefined }}},
  {x: { y: null }},
  {x: []},
];

console.log(nodes.map(n => exists(n, "x.y.z")));

Upvotes: 0

Mario Santini
Mario Santini

Reputation: 3003

If you just want to know if an object has a particular property, no matter where in the prototype chain, you could use the in operator:

if (myprop in myobj) {
    ...
}

Consider that his method will check all the properties and method that your object has and the method it get from the 'language'. As an example:

var o = {
    "myprop": true
};

if ("toString" in o) {
    console.log('toString exists');
}

It prints out 'toString exists'.

If you're interested in checking just inside the object, you have to use:

if (Object.hasOwnProperty.call(myobject, myprop)) {
    ...
}

This avoids the inherited method like toString and hasOwnProperty.

The dirty way is using the !! method:

if (!!myobject[myprop]) {
    ....
}

This way force to convert any myobject[myprop] to a boolean value. The issue with this, is when you could have values that could convert in false, like empty string or null or undefined or, of course, a boolean false!

Upvotes: 0

Chen usher
Chen usher

Reputation: 1

Use Object's hasOwnProperty(prop) for this task.

if (extra.hasOwnProperty('field1') && extra.field1.hasOwnProperty('foo')) {
    // ...
}

Upvotes: 0

Yosvel Quintero
Yosvel Quintero

Reputation: 19060

You can use Object.prototype.hasOwnProperty() as well as in operator. But for simplicity you can check the existence of properties like this:

if (extra.field1 && extra.field1.foo ) {
    // ...
}

Upvotes: 3

Nina Scholz
Nina Scholz

Reputation: 386522

You could use the in operator.

The in operator returns true if the specified property is in the specified object.

if ('field1' in extra && 'foo' in extra.field1) {
    // true for foo
}

Upvotes: 4

Pablo Lozano
Pablo Lozano

Reputation: 10342

You always will have to check both fields, but you can write it in different ways. If you are sure that you are checking objects, then the following code would be safe enough:

if (extra.field1) { //if field1 is not null / undefined / zero / empty string / false
  if (extra.field.foo) {...}
  ...
}

That won't be safe if field1 can be 0 or an empty string, because both are "falsy" values

Upvotes: 0

Related Questions