Питання Як перевірити "невизначені" в JavaScript? [дублікат]


На це питання вже є відповідь тут:

Який найбільш підходящий спосіб перевірити, чи є змінна невизначена в JavaScript? Я бачив кілька можливих способів:

if (window.myVariable)

Or

if (typeof(myVariable) != "undefined")

Or

if (myVariable) //This throws an error if undefined. Should this be in Try/Catch?

1875
2017-08-02 17:53


походження


Ви хочете перевірити тільки  undefined, або null так само? - Nick Craver♦
Перевір це stackoverflow.com/questions/27509/... - Amr Badawy
@ Роберт - це питання має прийняту відповідь, що відповіді тут виявилися неправильними - Daniel Schaffer
Побачити: Як перевірити неочікуване в javascript?, і чи є змінна невизначеною? і Як обробляти "undefined" в javascript - Shog9♦
Це "дублікат" стосується властивостей об'єкта, тому деякі відповіді не дуже добре стосуються цього питання, запитуючи про змінні. - DCShannon


Відповіді:


Якщо ви зацікавлені в з'ясуванні того, чи була оголошена змінна, незалежно від її значення, тоді використовуйте in Оператор - це найбезпечніший спосіб піти. Розглянемо цей приклад.

// global scope
var theFu; // theFu has been declared, but its value is undefined
typeof theFu; // "undefined"

Але це не може бути призначеним результатом для деяких випадків, оскільки змінна або властивість була оголошена, але просто не ініціалізована. Використовувати in Оператор для більш надійної перевірки.

"theFu" in window; // true
"theFoo" in window; // false

Якщо ви зацікавлені в знанні, чи не була оголошена змінна або вона має значення undefined, а потім використовуйте typeof оператор

if (typeof myVar != 'undefined')

The typeof Оператор гарантовано повертає рядок. Прямі порівняння проти undefined є клопітно як undefined може бути перезаписаний.

window.undefined = "omg";
"omg" == undefined // true

Як зазначив @CMS, це було виправлено в ECMAScript 5th ed., І undefined не є можливим для запису.

if (window.myVar) буде також включати ці фальшиві значення, тому він не дуже надійний:

помилковий
0
""
NaN
нуль
невизначено

Дякуємо @CMS, зазначивши, що ваш третій випадок - if (myVariable) може також викинути помилку у двох випадках. Перший - це коли змінна не визначена, яка кидає а ReferenceError.

// abc was never declared.
if (abc) {
    // ReferenceError: abc is not defined
} 

Інший випадок полягає у визначенні змінної, але має функцію getter, яка виводить помилку під час викликання. Наприклад,

// or it's a property that can throw an error
Object.defineProperty(window, "myVariable", { 
    get: function() { throw new Error("W00t?"); }, 
    set: undefined 
});
if (myVariable) {
    // Error: W00t?
}

2158
2017-08-02 17:58



@ Анураг, третій випадок буде кидати ReferenceError якщо myVariable не оголосив... - CMS
@ Анураг, ласкаво просимо, оскільки ви говорите про ES5, можливо варто згадати про це undefined тепер описується як непридатний для запису, не налаштовується та не переліт. Так, window.undefined = "omg"; просто просто відмовляться або кидають під суворий режим. - CMS
Чи можна перевизначити "typeof"? - CHI Coder 007
typeof - це мовне твердження, воно не може бути перевизначено, навіть якщо / else / while / for / function та ін. - MooGoo
undefined незмінна в сучасні браузери. Налаштування window.undefined нічого не робить. - Paul S.


Я особисто використовую

myVar === undefined

Попередження: зверніть увагу, що === використовується == і це myVar був раніше оголосив (ні визначений)


мені не подобається typeof myVar === "undefined". Я думаю, це довго забитий і непотрібний. (Я можу отримати те ж саме з меншим кодом.)

Тепер деякі люди змусять зболіти, читаючи це, кричачи: "Зачекай! WAAITTT !!! undefined можна перевизначити! "

Прохолодно Я знаю, що це. Знову ж таки, більшість змінних у Javascript можна перевизначити. Якщо ви ніколи не використовуватимете вбудований ідентифікатор, який можна буде перевизначити?

Якщо ви дотримуєтеся цього правила, добре для вас: ви не лицемір.

Справа в тому, що для того, щоб робити багато справжньої роботи в JS, розробники повинні спиратися на переосмислені ідентифікатори, щоб бути такими, якими вони є. Я не чую людей, які говорять мені, що я не повинен користуватися setTimeout тому що хтось може

window.setTimeout = function () {
    alert("Got you now!");
};

Підсумок, аргумент "можна перевизначити", щоб не використовувати сировину === undefined це фальш

(Якщо ви все ще налякані undefined чому ти сліпо інтегрує тестований код бібліотеки на свою кодову базу? Або ще простіше: інструмент для маскування.)


Також, як і typeof підхід, ця методика може "виявити" незадекларовані змінні:

if (window.someVar === undefined) {
    doSomething();
}

Але обидва ці техніки витікають у своїй абстракції. Я закликаю вас не використовувати це чи навіть

if (typeof myVar !== "undefined") {
    doSomething();
}

Розглянемо:

var iAmUndefined;

Щоб спіймати чи ні зазначену змінну, чи ні, може знадобитися вдатися до in оператор (У багатьох випадках ви можете просто прочитати код O_o).

if ("myVar" in window) {
    doSomething();
}

Але почекай! Там більше! Що робити, якщо відбувається магічне ланцюг прототипу ...? Тепер навіть начальник in Оператора не вистачає. (Добре, я зробив тут про цю частину, за винятком сказати, що в 99% випадків, === undefined (і **** кашель **** typeof) працює просто чудово. Якщо ви дійсно дбаєте про це, ви можете про це самостійно прочитати.)


888
2017-08-02 18:26



Це трохи більше імовірно undefined може бути перевизначено, просто тому, що люди використовують його для таких перевірок. Деякі люди звично ставлять константу на лівій стороні під час виконання таких перевірок: if (undefined == someVariable). Для цього потрібно лише помилково перевизначити undefined: if (undefined = someVariable). - Tim Down
Я ніколи не пишу кодекс, який має undefined на LHS. Навіть якщо б я зробив це те, що я користуюсь === замість == робить помилку надзвичайно малоймовірною. Але той факт, що == це неправильно - це більше турбуватися. У будь-якому випадку така помилка зазвичай легко знайти. Вид, як ця помилка: typeof x == "undefned". - Thomas Eding
Як це може бути виправлено 41 раз, це просто не працює. Якщо myVar це дійсно невизначено, код викине помилку, і його легко перевірити - jsfiddle.net/WcM5g Правильний шлях є typeof myVar === 'undefined'. - this.lau_
@ Лауренс: жарт правильно? Це передбачає, що змінна була оголошена певним чином або іншим, наприклад, a var ключове слово або параметр функції. Я б продавав свою душу, перш ніж я (навмисно) написав код, який намагався діяти на незадекларованих змінних в будь-який спосіб. Пам'ятайте, що незареєстровані та невизначені - це два різних поняття в JS. - Thomas Eding
@Andy In C (і C ++), як звичайна, так і хороша практика перевернути операнди, як це, щоб уникнути помилок. if (NULL = myVar) не скомпілюється і миттєво спіймається, в той час як if (myVar = NULL) створює помилку, яка може бути важко відстежувати залежно від того, який інший код навколо нього. Сучасні компілятори повинні надати вам попередження, але багато досвідчених програмістів C вже розробили звичку обмінювати замовлення. - GrandOpener


Використовуючи typeof це моє бажання. Він буде працювати, коли змінна ніколи не була оголошена, на відміну від будь-якого порівняння з == або === оператори або типу примусу за допомогою if. (undefined, на відміну від null, також може бути перевизначено в середовищах ECMAScript 3, що робить його ненадійним для порівняння, хоча майже всі загальні середовища тепер сумісні з ECMAScript 5 або вище).

if (typeof someUndeclaredVariable == "undefined") {
    // Works
}

if (someUndeclaredVariable === undefined) { 
    // Throws an error
}

149
2017-08-02 18:05



Можливо, ви захочете перевірити, чи певна глобальна змінна, що представляє частину функціональності, вже визначена. Наприклад, бібліотечний код може перевірити, чи бібліотека раніше не була включена. - Tim Down
'xyz' у вікні або 'xyz' у себе є набагато краще - Jamie Pate
@JamiePate: Просто ясно, я не погоджуюсь з цим 'xyz' in window це краща відповідь, ніж typeof xyz == "undefined" тому що тестування неправильно. The in Оператор перевіряє існування власності, незалежно від його значення, тоді як питання щонайменше, як видається, запитує, як перевірити, чи є значення змінної undefined. Можливо, кращим прикладом для мене було б вибрати var foo; "foo" in window; це повертається вірно, поки foo безумовно, невизначений. - Tim Down
@JamiePate: чому? xyz === undefined краще ніж typeof xyz == "undefined"? Погодьтеся, про глобали, але з двох нас тільки ви рекомендували перевірити властивості window. - Tim Down
У більшості випадків це є зайвим (і менш читабельним). Якщо ви знаєте, що xyz є оголошеною змінною, то чому виникає додаткова проблема? Контроль типу та порівняння рядків набагато повільніше в деяких браузерах, тому, якщо ви робите це багато в жорсткому циклі, ви втратите певну продуктивність. jsperf.com/type-of-undefined-vs-undefined/6 - Jamie Pate


Ви повинні використовувати typeof .

if (typeof something != "undefined") {
    // ...
}

51
2018-06-06 20:22



Або просто something !== undefined, якщо ви вже зробили це var undefined, попередньо обережно. - James
Приємно бачити, що ви зараз додавали котирування. Однак, як згадувалося в моя відповідь, відзначимо, що суворе порівняння (!==) у цьому випадку не є необхідним, оскільки typeof завжди повертає рядок. - Mathias Bynens
Матіас: використовуючи суворе або не суворе порівняння, це питання особистого смаку. Обидва завжди будуть працювати, і ні коректніше. Це може залежати від того, чи є ваша позиція за умовчанням завжди застосовувати строге порівняння, якщо не вимагає спеціального примусу типу (як це було рекомендовано Крокфордом), чи ви віддаєте перевагу використовувати не суворе порівняння, за винятком випадків, коли потрібна суворість. - Tim Down


Якщо це невизначено, воно не буде рівним рядку, що містить символи "undefined", оскільки рядок не визначено.

Ви можете перевірити тип змінної:

if (typeof(something) != "undefined") ...

Іноді навіть не потрібно перевіряти тип. Якщо значення змінної не може визначити значення false, коли він встановлений (наприклад, якщо це функція), то ви можете просто оцінити змінну. Приклад:

if (something) {
  something(param);
}

20
2018-06-06 20:23



Немає необхідності в дужках: typeof це оператор, а не функція. - Tim Down
@Tim - його можна використовувати в обох напрямках. - Nick Craver♦
@Tim: @Nick правильно. Побачити developer.mozilla.org/en/Core_Javascript_1.5_Reference/... - Mathias Bynens
Так, я це знаю працює з дужками, що полягає в тому, що круглі дужки тут утворюють оператор групування, який просто оцінює і повертає операнд всередині. Я просто сказав, що вони не потрібні. - Tim Down


Деякі сценарії, що ілюструють результати різних відповідей: http://jsfiddle.net/drzaus/UVjM4/

(Зверніть увагу, що використання var за 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

17
2018-01-13 15:39



зверніть увагу на використання undefined в межах обгортки; це не тільки захищає від (незвичайного) випадку "о, але undefined може бути перевизначено "", але також "допомагає" з мінімізацією. - drzaus


if (typeof foo == 'undefined') {
 // Do something
};

Зауважте, що строге порівняння (!==) у цьому випадку не є необхідним, оскільки typeof завжди повертає рядок.


16
2018-06-06 20:26



Що з комою (};)? - James
@ J-P: точку з комою після закриваючої фіксації - це просто порожнє твердження. - Gumbo
@ Гумбо, вибачте, що я мав намір запитати: "Яка мета - виготовити півколон?" - James
Я не зіткнувся з мінфіпером, який не може обробити if(){} без a ; ... Які мініфайли ви називаєте? Ви кажете, що це, як ви закінчуєте кожне інше твердження ... Я гадаю, це правда. Але, блок твердження {} це вже власне твердження. Додавання a ; робить два твердження технічно. Синтаксично це зайве. Навіть автоматична вставка з двокрапкою не додасть туди напівтону ... - James
@ J-P: Я думаю, я почав робити це багато років тому після прочитання Пакувальну документацію. Пакер очікує точку з комою function() {} декларації Ти маєш рацію - очевидно, це не потрібно після if заяви, але як-то я все ще думаю, що це має сенс. - Mathias Bynens