2015-02-12 7 views
2

Есть ли лучший способ сделать это?Зависимый тип объекта Проверка Javascript кажется избыточным

Если я это сделать:

if(typeof someObject[bar][foo] == "function"){ 
     // Do something 
    } 

я получаю ошибку someObject[bar][foo] is not an object которой он со ссылкой на someObject[bar] если bar не существует. Это означает, что код предполагает, что вы знаете, что определено значение someObj[bar]. Так что мое решение было было это:

if(typeof someObj[bar] === "object"){ 
     if(typeof someObject[bar][foo] == "function"){ 
     // Do something 
    } 
} 

Если мы хотим, чтобы приложить усилия, чтобы сократить строки коды и сделать хороший, чистый, читаемый код, то выглядит излишним и некрасиво. Есть ли лучший способ сделать это без необходимости проходить через два if баллов? Я понимаю, что дело не в этом, но мне интересно, есть ли лучший способ.

+0

вы пробовали 'если (someObj.hasOwnProperty (бар)) {} '? Нет привязанных строк ... ofcourse –

+0

Проверьте это fddle http://jsfiddle.net/4rjjxdzh/ – PashaB

+0

@PashaB, вот что я имею в виду: https://jsfiddle.net/powerphillg5/mobsrut5/ Посмотрите на журнал. –

ответ

1

Боюсь, что нет простого объяснения.

В каком обстоятельстве/ситуации вы ожидаете, что объект будет вести себя условно? Чтобы дать вам пример того, что я использую ... чтобы продвинуться вперед ... и в попытке сделать как можно более простым одновременно ...

  • Вы перебираете весь набор массивов как объекты?
  • Можете ли вы доверять объекту, чтобы вы уже знали, чего ожидать?
  • сравнение объектов для разных типов данных? .

[Мне нужно некоторое редактирование: s]

/** 
    * @description Get an object from a list of objects by searching for a key:value pair 
    * @param {Object} obj : -literal, json 
    * @param {String} val : the value you seek 
    * @param {String} key : the key 
    * @param {Boolean} isTypeComparison : if set to true, the key and value will be checked against it's type as well 
    */ 
    getObjectProperty: function (obj, val, key, isTypeComparison) { 
     var property, o; 

     for (property in obj) { 
      if (obj.hasOwnProperty(property)) { 
       if (typeof obj[property] === 'object') { 
        o = this.getObjectProperty(obj[property], val, key); 
        if (o) { 
         break; 
        } 
       } else { 
        // found a property which is not an object 
        if (isTypeComparison) { 
         if (property === key && obj[property] === val) { 
          // we got a match 
          o = obj; 
          break; 
         } 
        } else { 
         if (property == key && obj[property] == val) { 
          // we got a match 
          o = obj; 
          break; 
         } 
        } 
       } 
      } 
     } 

     return o || undefined; 
    }, 

Чтобы добавить какое-то ценность для вашего вопроса, во всех этих петлях выше вы видите борьбу с ожиданием. Я использовал этот код для поиска в списке контактов ajax, прикрепленного к списку. Поэтому вам определенно нужно написать больше кода для удовлетворения требований к глубине и доверию.

1
if(someObject.bar && someObject.bar.foo && typeof someObject.bar.foo === "function"){ 
    ... 
} 

или такой же, но с лучшей видимости стиля нотации:

if(someObject.bar 
    && someObject.bar.foo 
    && typeof someObject.bar.foo === "function"){ 
     ... 
} 
1

Если вы обобщили свою проблему, вы в основном спрашиваете, можете ли вы проверить какой-то «путь» в объекте как законный. То, как я сделал бы это с функции, которая принимает объект и желаемый «путь»:

function has(obj, path){ 
    var temp = obj; 
    var path = path.split('.'); 
    for(var i = 0; i < path.length; i++){ 
     if(temp[path[i]]) 
      temp = temp[path[i]];//path still exists 
     else 
      return false;//path ends here 
    } 
    return true;//the whole path could be followed 
} 

В этом примере используется путь, пройденный как «bar.foo», но вы можете легко настроить для массива [ . «бар», «Foo»] или так, чтобы это переменное количество аргументов, переданных в

Это сделает ваш пример:

if(has(someObject, bar + '.' + foo)){ 
    if(typeof someObject[bar][foo] == "function"){ 
     // Do something 
    } 
} 

Хотя это не уменьшает этот пример в конкретных, если у вас был гораздо более длинный путь к поиску, это могло бы значительно сократить, если бы сообщения были объединены вместе.

Вы можете изменить функцию так, что она возвращает значение, заданное по пути она должна существовать, а не правда, так что вы имеете дело только с одной строкой:

function get(obj, path){ 
    var temp = obj; 
    var path = path.split('.'); 
    for(var i = 0; i < path.length; i++){ 
     if(temp[path[i]] !== undefined) 
      temp = temp[path[i]];//path still exists 
     else 
      return undefined;//path ends here 
    } 
    return temp;//the whole path could be followed 
} 

if(typeof get(someObject, bar + '.' + foo) === 'function'){ 
    //do something 
} 
+0

миниатюрная версия для массива в качестве второго аргумента: function get (o, p) {for (i = 0; i

Смежные вопросы