2015-09-24 2 views
1

Скажем, я хотел бы проверить, является ли свойство объекта Foo определяется или нет, я хотел бы использовать в этом случае:Javascript TypeOf неопределенных объектов Подствойство

typeof Foo.property != 'undefined' 

Но если не только свойство не существует, но и объект не определен, это приводит к ошибке.

Есть ли одна линия способ проверить, если свойство объекта определяется и возвращает ложь в следующих случаях:

  • если свойство объекта не определен
  • , если объект не является определены

ПОЧЕМУ Я ХОЧУ ЭТО: Я пишу сценарий в NodeJS, который использует класс, который будет использоваться в передней ванной d также, и вместо того, чтобы поддерживать два разных файла, которые в конечном итоге будут в основном одинаковыми, за исключением незначительных изменений для двух сред, я хотел бы провести различие между средами с некоторой базовой логикой ИФ.

ДРУГИЕ ВОЗМОЖНЫЕ ПРИМЕРЫ ИСПОЛЬЗОВАНИЯ: Допустим, мы имеем следующий объект:

function Foo() { 
    this.case1={ 
     info1: 'something', 
     info2: 'something', 
     ..... 
     info1000: 'something' 
    } 

    this.case2={ 
     info1: 'something', 
     info2: 'something', 
     ...... 
     info1000: 'something' 
    } 
} 

Если я хотел бы решить, какой случай относится ко мне, и решение лежит в одной из внутренней Информация х, я сначала нужно проверить, если соответствующий случай существует, а затем, если соответствующая информация существует (2 условия):

if (typeof Foo.case1 != 'undefined') && (typeof Foo.case1.info1 != 'undefined') 

Если это гораздо глубже вложенный объект, там будет много проверки состояния и ввода, получить базовый i nformation: если case1 вообще не существует, я буду использовать case2.

ответ

1

Хорошо, я придумал малая функция, которая на начальном тестировании делает то, что я хотел, но я только проверил его, как 5 минут, так что может быть ошибки в этом, если да, пожалуйста, укажите это:

function isDefined(path, namespace) { 
    if (typeof namespace == 'undefined') { 
     namespace=global; 
     // global is the default namespace for NodeJS, 
     // change this to window if you use it in a browser 
    } 
    path=path.split("."); 
    for (var i=0;i<path.length ;i++) 
    { 

     if (typeof namespace[path[i]] == 'undefined') return false; 
     else namespace=namespace[path[i]]; 
    } 

    return true; 
} 

Использование: если вы бы хотели протестировать, например, если Test.Test1.Test2.Test3.Test4.Test5.Test6 определен, вы можете нам e это примерно так:

if (isDefined('Test.Test1.Test2.Test3.Test4.Test5.Test6')===true) { 
    //it is defined 
} 
+0

Небольшой наконечник для переносимости; нейтральный для окружающей среды способ найти «глобальный» объект - запустить IIFE без аргументов вызова, а 'this' будет глобальным внутри. – Katana314

+0

К сожалению, я не знаю, что такое IIFE, но если вы хотите либо изменить мой ответ, либо добавить новый ответ, используя этот метод, я бы поднял/принял его :) –

+1

Немедленно вызывается выражение функции. Итак, вот так: 'var global; (function() {global = this;})(); ' – Katana314

4

Вы можете использовать статью и (&&).

typeof Foo !== 'undefined' && typeof Foo.property !== 'undefined' 

Или, проще говоря:

Foo !== undefined && Foo.property !== undefined 

Edit: Как David Titarenco отметил, что это работает из-за чего-то известного как оценка короткого замыкания. Это в основном означает, что если первая часть вычисляет значение false (Foo !== undefined), то вторая часть никогда не оценивается.

+2

Просто хотел указать (ради OP), что порядок операндов здесь важен. Это называется * оценка короткого замыкания *. –

+0

@DavidTitarenco Хорошая точка. Отредактировано, чтобы указать на это. –

+0

Полностью согласен с Mike C's, о котором я читал об этом в потрясающей книге под названием «Javascript» - хорошие детали Дугласа Крокфорда. –

1

Самый простой ответ, который приходит на ум. Это не так, 100% -strict, как ваша, но это заняло бы очень необычную ситуацию, чтобы разбить его:

if (Foo && 'property' in Foo) { 

Объект Foo оценивается как логическое значение. Нулевой или неопределенный тип будет ложным, любой объект будет истинным. Мы также проверяем «ключевую» сторону пары ключ/значение, а не значение. Технически возможно, что имеет ключ property, но для его фактического значения undefined. В этом случае это вернет false.

Одно предостережение: Если Foo другой тип значения: true, 12, function()..., то первое условие может пройти (но я не считаю, что вторая одна будет)

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