Getting object property properly in Javascript

I am working on a large Javascript codebase at the moment, dotted with code using Exceptions to control flow

function getChecklistUrl() {
    try {
        return dataLayerObject.config.checklist;
    } catch (e) {
        try {
            console.error('dataLayer', e);
        } catch (ignore) {}
    }
}

I could use conditional logic like this implementation of the same function

function getChecklistUrl() {
    if(typeof dataLayerObject == 'object'        &&
       'config' in dataLayerObject               &&
       typeof dataLayerObject.config == 'object' &&
       'checklist' in dataLayerObject.config     &&
       typeof dataLayerObject.config.checklist == 'object') {
        return dataLayerObject.config.checklist;
    }
    return null;
}

While it later feels long, a helper function can be written to reduce the pattern for such checks.

Is the former idiomatic for javascript? Is the later fragility (in different browsers / scripts) and better left before try/ catchin any case? Or is it just just evidence of laziness?

Edit

these objects are supposed to be “ordinary” objects, such as var obj = {}, so I don’t believe I am worried about the prototype chain here.

+4
4

, property in object && & typeof obj[property] == 'object', typeof . , obj.property , typeof undefined.

, , , , - :

function isObject(o) {
    return typeof o == 'object' && o !== null; // take care of the corner case that typeof null == 'object'
}

, , , :

function getChecklistUrl() {
    if(isObject(dataLayerObject) && 
       isObject(dataLayerObject.config) &&  
       isObject(dataLayerObject.config.checklist)) { 

        return dataLayerObject.config.checklist;
    }
    return null;
}

var dataLayerObject = {
    config: {
         checklist: ['array of stuff']
    }
}

function isObject(o) {
  return typeof o == 'object' && o !== null;
}

function getChecklistUrl() {
  if (isObject(dataLayerObject) &&
    isObject(dataLayerObject.config) &&
    isObject(dataLayerObject.config.checklist)) {

    return dataLayerObject.config.checklist;
  }
  return null;
}

console.log(getChecklistUrl()[0]);
Hide result

, IMHO.

- getter , null, :

function getObjProperty(obj, propString) {
    if(!isObject(obj) || !propString || typeof propString != 'string') {
        return null;                                 // make sure obj is an object and propString is a non-empty string
    } 

    var props = propString.split('.');
    for (var i = 0, l = props.length; i < l; i++) {
        var p = props[i];
        if(!isObject(obj[p])) { return null; }       // if current property isn't an object, return null
        obj = obj[p];                                // otherwise update the object to the next one down the property chain
    }
    return obj;
}

: getObjProperty(dataLayerObject, 'config.checklist');

var dataLayerObject = {
  config: {
    checklist: ['array of stuff']
  }
};

function isObject(o) {
  return typeof o == 'object' && o !== null;
}

function getObjProperty(obj, propString) {
  if (!isObject(obj) || !propString || typeof propString != 'string') {
    return null;
  }

  var props = propString.split('.');
  for (var i = 0, l = props.length; i < l; i++) {
    var p = props[i];
    if (!isObject(obj[p])) {  // 
      return null;
    } // if current property isn't an object, return null
    obj = obj[p]; // otherwise update the object to the next one down the property chain
  }
  return obj;
}

console.log(getObjProperty(dataLayerObject, 'config.checklist'));
Hide result

. , hasOwnProperty, , , , .

.

+2

javascript - Object.hasOwnProperty().

:

var Person = {
  first_name: 'Fred',
  last_name: 'Flintstone'
};

if ( 'object' === typeof Person && Person.hasOwnProperty('first_name' ) {
  window.alert('the property exists!');
}

- :

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
+6

- , , , , dataLayer , , , . , . "in" "hasOwnProperty", , , .

var getChecklistUrl = function getChecklistUrl() {
    return dataLayerObject && dataLayerObject.config && dataLayerObject.config.checklist || null;
}
0

, :

if ( typeof dataLayerObject == 'object' &&
     dataLayerObject.config &&
     dataLayerObject.config.checklist &&
     typeof dataLayerObject.config.checklist == 'object') {
  // do something
}

, , typeof. typeof , , .

0

Source: https://habr.com/ru/post/1615617/


All Articles