Обнаружение неопределенного свойства объекта

2533

Какой лучший способ проверить, является ли свойство объекта в JavaScript undefined?

Теги:
object
undefined

43 ответа

2431
Лучший ответ

Использование:

if (typeof something === "undefined") {
    alert("something is undefined");
}

Если переменная объекта имеет некоторые свойства, вы можете использовать то же самое, как это:

if (typeof my_obj.someproperties === "undefined"){
    console.log('the property is not available...'); // print into console
}
  • 9
    если что-то имеет значение null, то оно определено (как null), но вы можете также связать проверки. Досадная деталь приведенного выше кода заключается в том, что вы не можете определить функцию для проверки, ну, вы можете определить функцию ... но попробуйте ее использовать.
  • 5
    @ neu-rah, почему ты не можешь написать функцию? почему бы не что-то вроде этой работы? Кажется, это работает для меня. Есть ли дело, которое я не рассматриваю? jsfiddle.net/djH9N/6
Показать ещё 9 комментариев
837

Я считаю, что есть ряд неправильных ответов на эту тему. Вопреки распространенному мнению, "undefined" является не ключевым словом в JavaScript и может фактически иметь присвоенное ему значение.

Правильный код

Самый надежный способ выполнить этот тест:

if (typeof myVar === "undefined")

Это всегда возвращает правильный результат и даже обрабатывает ситуацию, когда myVar не объявляется.

Вырожденный код. НЕ ИСПОЛЬЗУЙТЕ.

var undefined = false;  // Shockingly, this is completely legal!
if (myVar === undefined) {
    alert("You have been misled. Run away!");
}

Кроме того, myVar === undefined вызовет ошибку в ситуации, когда myVar не объявлен.

  • 113
    +1 за то, что заметил, что myVar === undefined вызовет ошибку, если myVar не был объявлен
  • 8
    да - цитаты, видимо, жизненно необходимы. я предполагаю, что функция typeof возвращает строку (ожидаемого формата)
Показать ещё 16 комментариев
153

Несмотря на то, что я настоятельно рекомендую многие другие ответы здесь, typeof - плохой выбор. Его никогда не следует использовать для проверки того, имеют ли переменные значение undefined, поскольку оно действует как комбинированная проверка значения undefined и для того, существует ли переменная. В подавляющем большинстве случаев вы знаете, когда существует переменная, а typeof просто представит потенциал для молчащего сбоя, если вы создадите опечатку в имени переменной или в строковом литерале 'undefined'.

var snapshot = …;

if (typeof snaposhot === 'undefined') {
    //         ^
    // misspelled¹ – this will never run, but it won’t throw an error!
}
var foo = …;

if (typeof foo === 'undefned') {
    //                   ^
    // misspelled – this will never run, but it won’t throw an error!
}

Итак, если вы не обнаруживаете функцию обнаружения2, где существует неопределенность в отношении того, будет ли данное имя областью видимости (например, проверка typeof module !== 'undefined' как шаг в коде, специфичном для среды CommonJS), typeof является вредным выбором при использовании на переменная, а правильный вариант - прямое сравнение значения:

var foo = …;

if (foo === undefined) {
    ⋮
}

Некоторые распространенные заблуждения об этом включают:

  • что чтение "неинициализированной" переменной (var foo) или параметра (function bar(foo) { … }, называемое bar()) завершится с ошибкой. Это просто неверно: переменные без явной инициализации и параметры, которые не задавали значения, всегда становятся undefined и всегда находятся в области видимости.

  • что undefined можно перезаписать. Theres намного больше к этому. undefined не является ключевым словом в JavaScript. Вместо этого его свойство на глобальном объекте со значением Undefined. Однако, поскольку ES5, это свойство было доступно только для чтения и не настраивалось. Ни один современный браузер не позволит изменить свойство undefined, и с 2017 года это имеет место в течение длительного времени. Отсутствие строгого режима не влияет на поведение undefined s - оно просто делает утверждения типа undefined = 5 ничего не делать, а не бросать. Так как это не ключевое слово, вы можете объявить переменные с именем undefined, и эти переменные могут быть изменены, что делает этот одноразовый шаблон:

    (function (undefined) {
        // …
    })()
    

    более опасно, чем использование глобального undefined. Если вы должны быть совместимы с ES3, замените undefined на void 0 - не обращайтесь к typeof. (void всегда был унарным оператором, который оценивает значение Undefined для любого операнда.)

С тем, как переменные работают в стороне, время для решения актуального вопроса: свойства объекта. Нет смысла использовать typeof для свойств объекта. Предыдущее исключение в отношении обнаружения функции не применяется здесь - typeof имеет только специальное поведение для переменных, а выражения, которые ссылаются на свойства объекта, не являются переменными.

Это:

if (typeof foo.bar === 'undefined') {
    ⋮
}

всегда точно эквивалентен этому:

if (foo.bar === undefined) {
    ⋮
}

и принимая во внимание приведенный выше совет, чтобы не путать читателей о том, почему вы используете typeof, потому что имеет смысл использовать === для проверки равенства, поскольку он может быть реорганизован на проверку значения переменных позже, и потому, что он просто выглядит лучше, , вы всегда должны использовать === undefined ³ здесь.

Что-то еще, чтобы рассмотреть, когда дело доходит до свойств объекта, действительно ли вы хотите проверить на undefined вообще. Имя данного свойства может отсутствовать на объекте (при чтении значения undefined), присутствующего на самом объекте со значением undefined, присутствующим на прототипе объектов со значением undefined или присутствующим на любом из те, у которых значение не undefined. 'key' in obj расскажет вам, находится ли ключ в цепочке прототипов объектов, а Object.prototype.hasOwnProperty.call(obj, 'key') расскажет вам, находится ли он непосредственно на объекте. Я не буду вдаваться в подробности в этом ответе о прототипах и использовать объекты в виде карт с привязкой к клавишам, тем не менее, потому что он в основном предназначен для борьбы со всеми плохими советами в других ответах, независимо от возможных интерпретаций исходного вопроса. Прочитайте прототипы объектов на MDN для более!

¹ необычный выбор имени переменной для примера? это настоящий мертвый код из расширения NoScript для Firefox.
² не предполагают, что, не зная, в чем смысл, в общем, все в порядке. бонусная уязвимость, вызванная злоупотреблением динамической областью: Project Zero 1225
³ снова принимает среду ES5 + и что undefined ссылается на свойство undefined глобального объекта. замените void 0 в противном случае.

  • 0
    @BenjaminGruenbaum Правда, но полностью вводит в заблуждение. Любой нестандартный контекст может определять свой собственный undefined , скрывая контекст по умолчанию. Что для большинства практических целей имеет тот же эффект, что и перезапись.
  • 17
    @blgt Это параноидально и не имеет никакого отношения к чему-либо практическому. Каждый контекст может переопределять console.log, переопределять методы-прототипы Array и даже переопределять перехват Function.prototype.call` и изменять каждый раз, когда вы вызываете функцию в JavaScript. Защита от этого очень параноидальна и довольно глупа. Как я (и Minitech) сказал, вы можете использовать void 0 для сравнения с неопределенным, но опять же - это глупо и излишне.
Показать ещё 2 комментария
149

В JavaScript есть null, и есть undefined. Они имеют разные значения.

  • undefined означает, что значение переменной не определено; неизвестно, что это за значение.
  • null означает, что значение переменной определено и установлено в значение null (не имеет значения).

Мэрийн Хавербеке в своей бесплатной онлайн-книге "" Красноречивый JavaScript" (внимание мое):

Существует также аналогичное значение, null, значение которого "это значение определено, но оно не имеет значения". Разница в значении между undefined и нулем в основном академическая, и обычно это не очень интересно. В практических программах часто бывает необходимо проверить, имеет ли что-то значение ". В этих случаях может использоваться выражение something == undefined, потому что, хотя они не являются точно таким же значением, null == undefined будет выдавать true.

Итак, я думаю, лучший способ проверить, было ли что-то undefined:

if (something == undefined)

Надеюсь, это поможет!

Изменить: В ответ на ваше редактирование свойства объекта должны работать одинаково.

var person = {
    name: "John",
    age: 28,
    sex: "male"
};

alert(person.name); // "John"
alert(person.fakeVariable); // undefined
  • 39
    если (что-то == не определено) лучше написать так, как будто (что-то === не определено)
  • 0
    @Alsciende хорошие моменты, я немного изменил формулировку.
Показать ещё 5 комментариев
104

Что это значит: "undefined свойство объекта?

На самом деле это может означать две совершенно разные вещи! Во-первых, это может означать свойство, которое никогда не было определено в объекте, и, во-вторых, это может означать свойство со значением undefined. Посмотрите на этот код:

var o = { a: undefined }

Является o.a undefined? Да! Его значение undefined. Является o.b undefined? Конечно! Нет никакого свойства 'b' вообще! Хорошо, посмотрите, как разные подходы ведут себя в обеих ситуациях:

typeof o.a == 'undefined' // true
typeof o.b == 'undefined' // true
o.a === undefined // true
o.b === undefined // true
'a' in o // true
'b' in o // false

Мы можем ясно видеть, что typeof obj.prop == 'undefined' и obj.prop === undefined эквивалентны, и они не различают эти разные ситуации. И 'prop' in obj может обнаружить ситуацию, когда свойство не было определено вообще и не обращает внимания на значение свойства, которое может быть undefined.

Итак, что делать?

1) Вы хотите знать, является ли свойство undefined первым или вторым значением (наиболее типичная ситуация).

obj.prop === undefined // IMHO, see "final fight" below

2) Вы хотите просто знать, имеет ли объект какое-то свойство и не заботится о его значении.

'prop' in obj

Примечания:

  • Вы не можете одновременно проверять объект и его свойство. Например, этот x.a === undefined или этот typeof x.a == 'undefined' вызывает ReferenceError: x is not defined, если x не определен.
  • Переменная undefined - это глобальная переменная (так что на самом деле это window.undefined в браузерах). Он поддерживается с ECMAScript 1st Edition, а с ECMAScript 5 он доступен только для чтения. Поэтому в современных браузерах он не может быть переопределен до истины, как многие авторы любят пугать нас, но это все еще верно для старых браузеров.

Финальный бой: obj.prop === undefined vs typeof obj.prop == 'undefined'

Плюсы obj.prop === undefined:

  • Это немного короче и выглядит немного красивее
  • Механизм JavaScript даст вам сообщение об ошибке, если у вас есть с ошибкой undefined

Недостатки obj.prop === undefined:

  • undefined может быть переопределен в старых браузерах

Плюсы typeof obj.prop == 'undefined':

  • Это действительно универсально! Он работает в новых и старых браузерах.

Недостатки typeof obj.prop == 'undefined':

  • 'undefned' (с ошибкой) здесь просто строковая константа, поэтому механизм JavaScript не может помочь вам, если у вас есть с ошибкой, как будто я просто сделал.

Обновление (для серверного JavaScript):

Node.js поддерживает глобальную переменную undefined как global.undefined (ее также можно использовать без префикса 'global'). Я не знаю о других реализациях серверного JavaScript.

  • 0
    @ Берги спасибо за ваш комментарий. Я исправил свой ответ. В свою защиту могу сказать, что в настоящее время (по состоянию на v.0.10.18) официальная документация Node.js ничего не говорит о undefined как члене global . Также нет console.log(global); ни for (var key in global) { ... } не показывает undefined в качестве члена global . Но тест как 'undefined' in global шоу показывает обратное.
  • 3
    Он не нуждался в дополнительной документации, так как он находится в спецификации EcmaScript , в которой также говорится, что [[Enumerable]] является ложным :-)
Показать ещё 3 комментария
62

Проблема сводится к трем случаям:

  • Объект имеет свойство и его значение не undefined.
  • Объект имеет свойство и его значение undefined.
  • Объект не имеет свойства.

Это говорит нам о чем-то важном:

Существует разница между членом undefined и определенным членом со значением undefined.

Но, к несчастью, typeof obj.foo не говорит нам, какой из трех случаев мы имеем. Однако мы можем объединить это с "foo" in obj, чтобы отличить случаи.

                               |  typeof obj.x === 'undefined' | !("x" in obj)
1.                     { x:1 } |  false                        | false
2.    { x : (function(){})() } |  true                         | false
3.                          {} |  true                         | true

Стоит отметить, что эти тесты одинаковы для null записей тоже

                               |  typeof obj.x === 'undefined' | !("x" in obj)
                    { x:null } |  false                        | false

Я бы сказал, что в некоторых случаях имеет смысл (и яснее) проверить, есть ли это свойство, чем проверка того, является ли это undefined, и единственный случай, когда эта проверка будет различной, - это случай 2, редкий случай фактической записи в объект со значением undefined.

Например: я только что переработал кучу кода, который имел кучу проверок, имел ли объект заданное свойство.

if( typeof blob.x != 'undefined' ) {  fn(blob.x); }

Который был яснее при написании без проверки на undefined.

if( "x" in blob ) { fn(blob.x); }

Но, как уже упоминалось, это не совсем то же самое (но более чем достаточно для моих нужд).

  • 9
    Привет майкл Отличное предложение, и я думаю, что оно делает вещи чище. Однако я обнаружил, что при использовании! оператор с "в". Вы должны сказать if (!("x" in blob)) {} с квадратными скобками внутри, потому что! Оператор имеет приоритет над «в». Надеюсь, что это помогает кому-то.
  • 0
    Извините Майкла, но это неверно или, по крайней мере, вводит в заблуждение в свете первоначального вопроса. «in» не является достаточным способом проверить, имеет ли свойство объекта тип неопределенного. Для доказательства, пожалуйста, смотрите эту скрипку: jsfiddle.net/CsLKJ/4
Показать ещё 4 комментария
40
if ( typeof( something ) == "undefined") 

Это работало для меня, а другие - нет.

  • 47
    паренсы не нужны, так как typeof является оператором
  • 12
    Но они проясняют, что проверяется. В противном случае это может быть прочитано как typeof (something == "undefined") .
Показать ещё 4 комментария
34

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

typeof x;                      // some string literal "string", "object", "undefined"
if (typeof x === "string") {   // === is redundant because we already know typeof returns a string literal
if (typeof x == "string") {    // sufficient
  • 0
    Отличный момент, Эрик. Есть ли снижение производительности при проверке типа?
  • 5
    @Simon: совсем наоборот - можно ожидать небольшого снижения производительности, если избегать принуждения в случае «===». Быстрый и грязный тест показал, что '===' на 5% быстрее, чем '==' в FF5.0.1
Показать ещё 5 комментариев
20

Перекрестный ответ на мой ответ по связанному вопросу Как проверить наличие "неопределенного" в JavaScript?

Специфично для этого вопроса, см. someObject.<whatever> примеры с someObject.<whatever>.


Некоторые сценарии, иллюстрирующие результаты различных ответов: http://jsfiddle.net/drzaus/UVjM4/

(Обратите внимание, что использование var for in тестах имеет значение, когда используется оболочка с заданной областью действия)

Код для справки:

(function(undefined) {
    var definedButNotInitialized;
    definedAndInitialized = 3;
    someObject = {
        firstProp: "1"
        , secondProp: false
        // , undefinedProp not defined
    }
    // var notDefined;

    var tests = [
        'definedButNotInitialized in window',
        'definedAndInitialized in window',
        'someObject.firstProp in window',
        'someObject.secondProp in window',
        'someObject.undefinedProp in window',
        'notDefined in window',

        '"definedButNotInitialized" in window',
        '"definedAndInitialized" in window',
        '"someObject.firstProp" in window',
        '"someObject.secondProp" in window',
        '"someObject.undefinedProp" in window',
        '"notDefined" in window',

        'typeof definedButNotInitialized == "undefined"',
        'typeof definedButNotInitialized === typeof undefined',
        'definedButNotInitialized === undefined',
        '! definedButNotInitialized',
        '!! definedButNotInitialized',

        'typeof definedAndInitialized == "undefined"',
        'typeof definedAndInitialized === typeof undefined',
        'definedAndInitialized === undefined',
        '! definedAndInitialized',
        '!! definedAndInitialized',

        'typeof someObject.firstProp == "undefined"',
        'typeof someObject.firstProp === typeof undefined',
        'someObject.firstProp === undefined',
        '! someObject.firstProp',
        '!! someObject.firstProp',

        'typeof someObject.secondProp == "undefined"',
        'typeof someObject.secondProp === typeof undefined',
        'someObject.secondProp === undefined',
        '! someObject.secondProp',
        '!! someObject.secondProp',

        'typeof someObject.undefinedProp == "undefined"',
        'typeof someObject.undefinedProp === typeof undefined',
        'someObject.undefinedProp === undefined',
        '! someObject.undefinedProp',
        '!! someObject.undefinedProp',

        'typeof notDefined == "undefined"',
        'typeof notDefined === typeof undefined',
        'notDefined === undefined',
        '! notDefined',
        '!! notDefined'
    ];

    var output = document.getElementById('results');
    var result = '';
    for(var t in tests) {
        if( !tests.hasOwnProperty(t) ) continue; // bleh

        try {
            result = eval(tests[t]);
        } catch(ex) {
            result = 'Exception--' + ex;
        }
        console.log(tests[t], result);
        output.innerHTML += "\n" + tests[t] + ": " + result;
    }
})();

И результаты:

definedButNotInitialized in window: true
definedAndInitialized in window: false
someObject.firstProp in window: false
someObject.secondProp in window: false
someObject.undefinedProp in window: true
notDefined in window: Exception--ReferenceError: notDefined is not defined
"definedButNotInitialized" in window: false
"definedAndInitialized" in window: true
"someObject.firstProp" in window: false
"someObject.secondProp" in window: false
"someObject.undefinedProp" in window: false
"notDefined" in window: false
typeof definedButNotInitialized == "undefined": true
typeof definedButNotInitialized === typeof undefined: true
definedButNotInitialized === undefined: true
! definedButNotInitialized: true
!! definedButNotInitialized: false
typeof definedAndInitialized == "undefined": false
typeof definedAndInitialized === typeof undefined: false
definedAndInitialized === undefined: false
! definedAndInitialized: false
!! definedAndInitialized: true
typeof someObject.firstProp == "undefined": false
typeof someObject.firstProp === typeof undefined: false
someObject.firstProp === undefined: false
! someObject.firstProp: false
!! someObject.firstProp: true
typeof someObject.secondProp == "undefined": false
typeof someObject.secondProp === typeof undefined: false
someObject.secondProp === undefined: false
! someObject.secondProp: true
!! someObject.secondProp: false
typeof someObject.undefinedProp == "undefined": true
typeof someObject.undefinedProp === typeof undefined: true
someObject.undefinedProp === undefined: true
! someObject.undefinedProp: true
!! someObject.undefinedProp: false
typeof notDefined == "undefined": true
typeof notDefined === typeof undefined: true
notDefined === undefined: Exception--ReferenceError: notDefined is not defined
! notDefined: Exception--ReferenceError: notDefined is not defined
!! notDefined: Exception--ReferenceError: notDefined is not defined
16

Если вы делаете

if (myvar == undefined )
{ 
    alert('var does not exists or is not initialized');
}

он не сработает, если переменная myvar не существует, потому что myvar не определен, поэтому script сломан и тест не имеет эффекта.

Поскольку объект окна имеет глобальную область (объект по умолчанию) вне функции, объявление будет прикреплено к объекту окна.

Например:

var myvar = 'test';

Глобальная переменная myvar такая же, как window.myvar или window ['myvar']

Чтобы избежать ошибок для проверки, когда существует глобальная переменная, лучше использовать:

if(window.myvar == undefined )
{ 
    alert('var does not exists or is not initialized');
}

Вопрос о том, действительно ли существует переменная, не имеет значения, ее значение неверно. В противном случае глупо инициализировать переменные с помощью undefined, и лучше использовать значение false для инициализации. Когда вы знаете, что все переменные, которые вы объявляете, инициализируются с помощью false, вы можете просто проверить его тип или полагаться на !window.myvar, чтобы проверить, имеет ли он правильное/допустимое значение. Таким образом, даже если переменная не определена, то !window.myvar то же самое для myvar = undefined или myvar = false или myvar = 0.

Когда вы ожидаете определенного типа, проверьте тип переменной. Чтобы ускорить тестирование состояния, вам лучше:

if( !window.myvar || typeof window.myvar != 'string' )
{
    alert('var does not exists or is not type of string');
}

Когда первое и простое условие истинно, интерпретатор пропускает следующие тесты.

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

(у)

15

Я не видел (надеюсь, что не пропустил это), кто-либо проверил объект перед свойством. Итак, это самый короткий и самый эффективный (хотя и не обязательно самый ясный):

if (obj && obj.prop) {
  // Do something;
}

Если obj или obj.prop undefined, null или "falsy", оператор if не будет выполнять блок кода. Обычно это желаемое поведение в большинстве операторов блока кода (в JavaScript).

  • 2
    Если вы хотите знать, почему это работает: Javascript: логические операторы и истина / ложь
  • 0
    если вы хотите присвоить свойство переменной, если она определена, не нулевая и не ложная, в противном случае используйте какое-либо значение по умолчанию, вы можете использовать: var x = obj && obj.prop || 'default';
Показать ещё 1 комментарий
12

В статье Изучение Abyss of Null и Undefined в JavaScript я прочитал, что фреймворки, такие как Underscore.js использует эту функцию:

function isUndefined(obj){
    return obj === void 0;
}
  • 3
    void 0 - это всего лишь краткий способ записи undefined (так как void, за которым следует любое выражение, возвращает), он сохраняет 3 символа. Это также может сделать var a; return obj === a; , но это еще один персонаж. :-)
  • 2
    void является зарезервированным словом, тогда как undefined не является, то есть, хотя undefined по умолчанию равен void 0 , вы можете присвоить значение undefined например, undefined = 1234 .
Показать ещё 1 комментарий
10

'if (window.x) {}' является безопасным с ошибкой

Скорее всего, вы хотите if (window.x). Эта проверка безопасна, даже если x не был объявлен (var x;) - браузер не выдает ошибку.

Пример: я хочу знать, поддерживает ли мой браузер API истории

if (window.history) {
    history.call_some_function();
}

Как это работает:

window - это объект, который содержит все глобальные переменные в качестве своих членов, и законно пытаться получить доступ к несуществующему элементу. Если x не было объявлено или не было установлено, то window.x возвращает undefined. undefined приводит к false, когда if() оценивает его.

  • 0
    Но что, если вы запустите в Node? typeof history != 'undefined' фактически работает в обеих системах.
9

Прочитав это, я поражен, что не видел этого. Я нашел несколько алгоритмов, которые будут работать для этого.

Никогда не определено

Если значение объекта никогда не было определено, это предотвратит возврат true, если он определен как null или undefined. Это полезно, если вы хотите вернуть true для значений, установленных как undefined

if(obj.prop === void 0) console.log("The value has never been defined");

Определено как undefined или никогда не определено

Если вы хотите, чтобы результат был true для значений, определенных со значением undefined, или никогда не определялся, вы можете просто использовать === undefined

if(obj.prop === undefined) console.log("The value is defined as undefined, or never defined");

Определено как значение ложности, undefined, null или никогда не определено.

Как правило, люди просили меня разработать алгоритм, если значение является ложным, undefined или null. Следующие работы.

if(obj.prop == false || obj.prop === null || obj.prop === undefined) {
    console.log("The value is falsy, null, or undefined");
}
  • 4
    Я думаю, что вы можете заменить последний пример на if (!obj.prop)
  • 0
    @StijndeWitt, вы можете, я был довольно неопытен, когда писал это, и мой английский, кажется, был столь же плохим, тем не менее, в ответе нет ничего неправильного
Показать ещё 1 комментарий
9
"propertyName" in obj //-> true | false
8

Вы можете получить массив всех undefined с помощью пути, используя следующий код.

 function getAllUndefined(object) {

        function convertPath(arr, key) {
            var path = "";
            for (var i = 1; i < arr.length; i++) {

                path += arr[i] + "->";
            }
            path += key;
            return path;
        }


        var stack = [];
        var saveUndefined= [];
        function getUndefiend(obj, key) {

            var t = typeof obj;
            switch (t) {
                case "object":
                    if (t === null) {
                        return false;
                    }
                    break;
                case "string":
                case "number":
                case "boolean":
                case "null":
                    return false;
                default:
                    return true;
            }
            stack.push(key);
            for (k in obj) {
                if (obj.hasOwnProperty(k)) {
                    v = getUndefiend(obj[k], k);
                    if (v) {
                        saveUndefined.push(convertPath(stack, k));
                    }
                }
            }
            stack.pop();

        }

        getUndefiend({
            "": object
        }, "");
        return saveUndefined;
    }

jsFiddle ссылка

  • 0
    Хотя это не повлияет на достоверность вашего кода, у вас есть опечатка: getUndefiend должен быть getUndefined .
7

Просто что-то не определено в JavaScript, не определено, не имеет значения, является ли оно свойством внутри Object/Array или просто как переменная...

В JavaScript есть typeof благодаря которому очень просто обнаружить неопределенную переменную.

Просто проверьте, является ли typeof whatever === 'undefined' и он вернет логическое значение.

Вот как isUndefined() знаменитая функция isUndefined() в AngularJs v.1x:

function isUndefined(value) {return typeof value === 'undefined';} 

Итак, как вы видите, функция получает значение, если это значение определено, она вернет false, в противном случае для неопределенных значений вернет true.

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

var stackoverflow = {};
stackoverflow.javascipt = 'javascript';
var today;
var self = this;
var num = 8;
var list = [1, 2, 3, 4, 5];
var y = null;

и мы проверяем их, как показано ниже, вы можете увидеть результаты перед ними в качестве комментария:

isUndefined(stackoverflow); //false
isUndefined(stackoverflow.javascipt); //false
isUndefined(today); //true
isUndefined(self); //false
isUndefined(num); //false
isUndefined(list); //false
isUndefined(y); //false
isUndefined(stackoverflow.java); //true
isUndefined(stackoverflow.php); //true
isUndefined(stackoverflow && stackoverflow.css); //true

Как вы видите, мы можем проверить что угодно, используя что-то подобное в нашем коде, как уже упоминалось, вы можете просто использовать typeof в своем коде, но если вы используете его снова и снова, создайте функцию, подобную угловой выборке, которую я разделяю, и продолжаю использовать повторно. как следующий шаблон кода DRY.

Также еще одна вещь, для проверки свойства объекта в реальном приложении, в котором вы не уверены, существует ли этот объект или нет, сначала проверьте, существует ли объект.

Если вы проверите свойство объекта и объект не существует, вы получите ошибку и остановите работу всего приложения.

isUndefined(x.css);
VM808:2 Uncaught ReferenceError: x is not defined(…)

Настолько просто, что вы можете заключить в оператор if, как показано ниже:

if(typeof x !== 'undefined') {
  //do something
}

Что также равно isDefined в Angular 1.x...

function isDefined(value) {return typeof value !== 'undefined';}

Также другие фреймворки javascript, такие как подчеркивание, имеют аналогичную проверочную проверку, но я рекомендую вам использовать typeof если вы уже не используете фреймворки.

Я также добавляю этот раздел из MDN, в котором есть полезная информация о typeof, undefined и void (0).

Строгое равенство и неопределенность
Вы можете использовать неопределенные и строгие операторы равенства и неравенства, чтобы определить, имеет ли переменная значение. В следующем коде переменная x не определена, а оператор if оценивается как true.

var x;
if (x === undefined) {
   // these statements execute
}
else {
   // these statements do not execute
}

Примечание: здесь должен использоваться оператор строгого равенства, а не стандартный оператор равенства, потому что x == undefined также проверяет, является ли x нулевым, а строгое равенство - нет. ноль не эквивалентно неопределенному. Смотрите операторы сравнения для деталей.


Тип оператора и неопределенный
В качестве альтернативы typeof может быть использован:

var x;
if (typeof x === 'undefined') {
   // these statements execute
}

Одной из причин использования typeof является то, что он не выдает ошибку, если переменная не была объявлена.

// x has not been declared before
if (typeof x === 'undefined') { // evaluates to true without errors
   // these statements execute
}

if (x === undefined) { // throws a ReferenceError

}

Тем не менее, этот вид техники следует избегать. JavaScript является статически ограниченным языком, поэтому, зная, объявлена ли переменная, можно прочитать, проверив, объявлена ли она в окружающем контексте. Единственное исключение - глобальная область, но глобальная область привязана к глобальному объекту, поэтому проверка существования переменной в глобальном контексте может быть выполнена путем проверки наличия свойства в глобальном объекте (используя оператор in, например).


Пустой оператор и неопределенный

Оператор void является третьей альтернативой.

var x;
if (x === void 0) {
   // these statements execute
}

// y has not been declared before
if (y === void 0) {
   // throws a ReferenceError (in contrast to 'typeof')
}

больше> здесь

7

Сравните с void 0, для терпения.

if (foo !== void 0)

Это не так много, как if (typeof foo !== 'undefined')

  • 3
    Но он выдаст ReferenceError, если foo не объявлен.
  • 1
    'use strict' !
Показать ещё 2 комментария
7

Решение неверно. В JavaScript,

null == undefined

вернет true, потому что оба они "casted" для логического значения и являются ложными. Правильный способ - проверить

if (something === undefined)

который является тождественным оператором...

  • 3
    Чтобы было ясно, === это равенство типов + (примитивное равенство | идентичность объекта), где примитивы включают строки. Я думаю, что большинство людей считают 'abab'.slice(0,2) === 'abab'.slice(2) интуитивным, если считать === оператором идентификации.
  • 1
    Неправильно. Это выдает ошибку, если переменная не была создана. Не следует голосовать. Используйте вместо этого typeof.
6

Существует красивый и элегантный способ присвоить заданное свойство новой переменной, если он определен или присвоить значение по умолчанию для него как резервную, если это undefined.

var a = obj.prop || defaultValue;

Это подходит, если у вас есть функция, которая получает дополнительное свойство конфигурации:

var yourFunction = function(config){

   this.config = config || {};
   this.yourConfigValue = config.yourConfigValue || 1;
   console.log(this.yourConfigValue);

}

Теперь выполнение

yourFunction({yourConfigValue:2});
//=> 2

yourFunction();
//=> 1

yourFunction({otherProperty:5});
//=> 1
6

Вот моя ситуация:

Я использую результат вызова REST. Результат должен быть проанализирован с JSON на объект JavaScript.

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

Используя этот пост, чтобы помочь мне защититься от этого, я попробовал это.

if( typeof restResult.data[0] === "undefined" ) { throw  "Some error"; }

В моей ситуации, если restResult.data [0] === "object", то я могу спокойно начать проверку остальных членов. Если undefined затем выбросить ошибку, как указано выше.

Я говорю, что для моей ситуации все предложения, приведенные выше в этом сообщении, не работали. Я не говорю, что я прав, и все ошибаются. Я вообще не мастер JavaScript, но, надеюсь, это поможет кому-то.

  • 0
    Ваш охранник typeof фактически не typeof ни от чего, с чем не может справиться прямое сравнение. Если restResult не определен или не объявлен, он все равно сгенерирует.
  • 0
    В вашем случае вы могли бы проще проверить, является ли массив пустым: if(!restResult.data.length) { throw "Some error"; }
5

Я использую if (this.variable) для проверки, если он определен. Простой if (variable), рекомендованный выше, не подходит для меня. Оказывается, он работает только тогда, когда переменная является полем какого-либо объекта, obj.someField, чтобы проверить, определено ли это в словаре. Но мы можем использовать this или window как объект словаря, поскольку любая переменная является полем в текущем окне, как я понимаю. Поэтому здесь есть тест

if (this.abc) alert("defined"); else alert("undefined");

abc = "abc";
if (this.abc) alert("defined"); else alert("undefined");

Сначала он обнаруживает, что переменная abc равна undefined, и она определена после инициализации.

5

Если вы используете Angular:

angular.isUndefined(obj)
angular.isUndefined(obj.prop)

Underscore.js:

_.isUndefined(obj) 
_.isUndefined(obj.prop) 
  • 2
    Как мне добавить 1 к переменной x ? Нужно ли Underscore или jQuery? (Удивительно , что люди будут использовать библиотеки для даже самых элементарных операций , таких как typeof проверки)
5

Просматривая комментарии, для тех, кто хочет проверить оба, это undefined или его значение равно null:

//Just in JavaScript
var s; // Undefined
if (typeof s == "undefined" || s === null){
    alert('either it is undefined or value is null')
}

Если вы используете библиотеку jQuery, тогда для обоих случаев будет достаточно jQuery.isEmptyObject(),

var s; // Undefined
jQuery.isEmptyObject(s); // Will return true;

s = null; // Defined as null
jQuery.isEmptyObject(s); // Will return true;

//Usage
if (jQuery.isEmptyObject(s)) {
    alert('Either variable:s is undefined or its value is null');
} else {
     alert('variable:s has value ' + s);
}

s = 'something'; // Defined with some value
jQuery.isEmptyObject(s); // Will return false;
  • 0
    jQuery также позаботится о любых проблемах совместимости между различными браузерами с различными API-интерфейсами JavaScript.
5

Все ответы неполны. Это правильный способ узнать, что существует свойство "определено как undefined":

var hasUndefinedProperty = function hasUndefinedProperty(obj, prop){
  return ((prop in obj) && (typeof obj[prop] == 'undefined')) ;
} ;

Пример:

var a = { b : 1, e : null } ;
a.c = a.d ;

hasUndefinedProperty(a, 'b') ; // false : b is defined as 1
hasUndefinedProperty(a, 'c') ; // true : c is defined as undefined
hasUndefinedProperty(a, 'd') ; // false : d is undefined
hasUndefinedProperty(a, 'e') ; // false : e is defined as null

// And now...
delete a.c ;
hasUndefinedProperty(a, 'c') ; // false : c is undefined

Слишком плохо, что это был правильный ответ, похоронен в неправильных ответах > _ <

Итак, для всех, кто проходит мимо, я дам вам undefineds бесплатно!!

var undefined ; undefined ; // undefined
({}).a ;                    // undefined
[].a ;                      // undefined
''.a ;                      // undefined
(function(){}()) ;          // undefined
void(0) ;                   // undefined
eval() ;                    // undefined
1..a ;                      // undefined
/a/.a ;                     // undefined
(true).a ;                  // undefined
4
function isUnset(inp) {
  return (typeof inp === 'undefined')
}

Возвращает false, если задана переменная, а true, если undefined.

Затем используйте:

if (isUnset(var)) {
  // initialize variable here
}
  • 4
    Нет, не делай этого. Требуется только очень простой тест, чтобы доказать, что вы не можете осмысленно обернуть тест typeof в функцию. Удивительно, что 4 человека проголосовали за это. -1.
3

Я хотел бы показать вам что-то, что я использую, чтобы защитить переменную undefined:

Object.defineProperty(window, 'undefined', {});

Это запрещает любому изменять значение window.undefined, тем самым уничтожая код на основе этой переменной. Если вы используете "use strict", все, что пытается изменить его значение, закончится ошибкой, в противном случае оно будет игнорироваться.

3

То же самое можно записать короче:

if (!variable){
    //do it if variable is Undefined
}

или

if (variable){
    //do it if variable is Defined
}
  • 1
    Ваш первый случай может быть вызван определенной переменной. Например, если переменная = 0, переменная! Сработает. Так что ваш ответ совершенно неверный.
  • 0
    Я думаю, что просто неправильная формулировка, я думаю, он имел в виду «сделай это, если переменная не определена или другое ложное значение», что часто является логикой, которую ищут люди.
Показать ещё 2 комментария
2

Я предлагаю три способа для тех, кто ожидает странных ответов:

function isUndefined1(val) {
    try {
        val.a;
    } catch (e) {
        return /undefined/.test(e.message);
    }
    return false;
}
function isUndefined2(val) {
    return !val && val+'' === 'undefined';
}
function isUndefined3(val) {
    const defaultVal={};
    return ((input=defaultVal)=>input===defaultVal)(val);
}
function test(func){
    console.group('test start :'+func.name);
    console.log(func(undefined));
    console.log(func(null));
    console.log(func(1));
    console.log(func("1"));
    console.log(func(0));
    console.log(func({}));
    console.log(func(function () { }));
    console.groupEnd();
}
test(isUndefined1);
test(isUndefined2);
test(isUndefined3);

isUndefined1:

Попытайтесь получить свойство входного значения, проверьте сообщение об ошибке, если оно существует. Если входное значение не определено, сообщение об ошибке будет неактивным TypeError: невозможно прочитать свойство "b" неопределенного

isUndefined2:

Преобразуйте значение ввода в строку для сравнения с "undefined" и убедитесь, что это отрицательное значение.

isUndefined3:

В js необязательный параметр работает, когда входное значение точно undefined.

2

От lodash.js.

var undefined;
function isUndefined(value) {
  return value === undefined;
}

Он создает LOCAL переменную с именем undefined которая инициализируется значением по умолчанию - реальным undefined, а затем сравнивает value с переменной undefined.

2

Использование:

Чтобы проверить, есть ли свойство undefined:

if (typeof something === "undefined") {
    alert("undefined");
}

Чтобы проверить, не является ли свойство undefined:

if (typeof something !== "undefined") {
    alert("not undefined");
}
1

вы также можете использовать прокси-сервер, он будет работать с вложенными вызовами, но потребует дополнительной проверки:

function resolveUnknownProps(obj, resolveKey) {
  const handler = {
    get(target, key) {
      if (
        target[key] !== null &&
        typeof target[key] === 'object'
      ) {
        return resolveUnknownProps(target[key], resolveKey);
      } else if (!target[key]) {
        return resolveUnknownProps({ [resolveKey]: true }, resolveKey);
      }

      return target[key];
    },
  };

  return new Proxy(obj, handler);
}

const user = {}

console.log(resolveUnknownProps(user, 'isUndefined').personalInfo.name.something.else); // { isUndefined: true }

поэтому вы будете использовать его как:

const { isUndefined } = resolveUnknownProps(user, 'isUndefined').personalInfo.name.something.else;
if (!isUndefined) {
  // do someting
}
1

Я удивлен, что еще не видел этого предложения, но он становится еще более специфичным, чем тестирование с помощью typeof. Используйте Object.getOwnPropertyDescriptor(), если вам нужно знать, было ли инициализировано свойство объекта с помощью undefined или если оно никогда не было инициализировано:

// to test someObject.someProperty
var descriptor = Object.getOwnPropertyDescriptor(someObject, 'someProperty');

if (typeof descriptor === 'undefined') {
  // was never initialized
} else if (typeof descriptor.value === 'undefined') {
  if (descriptor.get || descriptor.set) {
    // is an accessor property, defined via getter and setter
  } else {
    // is initialized with `undefined`
  }
} else {
  // is initialized with some other value
}
0

Простой способ проверить, существует ли ключ, использовать in

if (key in obj) {
  // do something
} else {
  // create key
}

const obj = {
  0: 'abc',
  1: 'def'
}

const hasZero = 0 in obj

console.log(hasZero) // true
0

Введенный в ECMAScript 6, теперь мы можем работать с undefined по-новому с помощью Proxies. Его можно использовать для установки значения по умолчанию для любых свойств, которые не существуют, поэтому нам не нужно каждый раз проверять, существует ли он на самом деле.

var handler = {
  get: function(target, name) {
    return name in target ? target[name] : 'N/A';
  }
};

var p = new Proxy({}, handler);
p.name = 'Kevin';
console.log('Name: ' +p.name, ', Age: '+p.age, ', Gender: '+p.gender)

Выведет ниже текст без каких-либо неопределенных значений.

Name: Kevin , Age: N/A , Gender: N/A
0

В библиотеке lodash есть несколько помощников:

isUndefined - проверить, если значение undefined.

_.isUndefined(undefined) // => true
_.isUndefined(null) // => false

имеет - проверить, содержит ли объект свойство

const object = { 'a': { 'b': 2 } }

_.has(object, 'a.b') // => true
_.has(object, 'a.c') // => false
0

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

var ojb ={
    age:12
}

if(ojb.hasOwnProperty('name')){
    console.log('property exist and not undefined');
}

Вышеуказанный метод возвращает true если он получил это свойство или свойство не неопределенным.

0

Я предполагаю, что вы тоже захотите проверить, что это либо undefined, либо null. Если это так, я предлагаю:

myVar == null

Это единственный раз, когда double equals очень полезен, поскольку он будет оценивать до true, когда myVar равен undefined или null, но будет оцениваться до false когда это другие значения, такие как 0, false, '' и NaN.

Это фактический исходный код для Lodash isNil.

  • 0
    Удивило, что это не получило больше голосов или комментариев. Что люди думают об этом?
0

Это, вероятно, единственная явная форма определения того, имеет ли существующее имя свойства явное и предполагаемое значение undefined; который, тем не менее, является JS-типом.

"propertyName" in containerObject && ""+containerObject["propertyName"] == "undefined";
>> true \ false

Это выражение вернет только true, если имя свойства данного контекста существует (истинно) и только если его предполагаемое значение явно undefined.

Не будет ложных срабатываний, таких как пустые или пустые строки нулей или пустые массивы и так далее. Это делает именно это. Проверяет, т.е. Гарантирует, что имя свойства существует (в противном случае это было бы ложным положительным), чем он явно проверяет, имеет ли его значение undefined например. of undefined Тип JS В нем строковая форма представления (буквально "undefined" ), поэтому == вместо ===, потому что дальнейшее преобразование невозможно. И это выражение вернет true только в том случае, если оба условия выполнены. например если имя свойства не существует, оно вернет false. Который является единственным правильным возвратом, поскольку несуществующие свойства не могут иметь значений, даже не undefined.

Пример:

containerObject = { propertyName: void "anything" }
>> Object { propertyName: undefined } 

// now the testing

"propertyName" in containerObject && ""+containerObject["propertyName"] == "undefined";
>> true

/* which makes sure that nonexistent property will not return a false positive
 * unless it is previously defined  */

"foo" in containerObject && ""+containerObject["foo"] == "undefined";
>> false
  • 0
    А что если свойство имеет строковое значение "undefined" ? ... как в containerObject = { propertyName: "undefined" }
  • 0
    @rockstar Вы говорите мне? Давай, просвети нас ...
Показать ещё 12 комментариев
-2

Вы хотите получить значение, если оно определено? Я бы использовал https://github.com/remy/undefsafe

Взятый с веб-сайта, это "простая функция для получения глубоких свойств объекта без получения" Невозможно прочитать свойство "X" undefined " .

-2

Object.hasOwnProperty(o, 'propertyname');

Однако это не проверяет цепочку прототипов.

  • 2
    Object.hasOwnProperty не будет работать Object.hasOwnProperty ; он проверяет, есть ли у Object свойство с именем, содержащимся в o . Вы, вероятно, имеете в виду Object.prototype.hasOwnProperty.call(o, 'propertyname') .
-6

если простой типof не работает, попробуйте это:

if(jQuery.type(variable) === "undefined") {// do something}
-16
if (somevariable == undefined) {
  alert('the variable is not defined!');
}

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

function isset(varname){
  return(typeof(window[varname]) != 'undefined');
}
  • 14
    Во-первых, когда некоторая переменная равна undefined, это не значит, что переменная не определена - это просто значение, которое не определено. Когда переменная не определена, этот код выдаст ошибку. Во-вторых, эта функция isset будет работать только для глобальных переменных.
  • 6
    Используйте === над ==
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню