Як перевірити наявність невизначеної чи нульової змінної у JavaScript?


500

У нашому коді JavaScript ми часто використовуємо таку схему коду

if (typeof(some_variable) != 'undefined' && some_variable != null)
{
    // Do something with some_variable
}

Чи є менш дослівний спосіб перевірки, який має той самий ефект?

На думку деяких форумів та літератури, що говорять просто, наступне повинно мати той же ефект.

if (some_variable)
{
    // Do something with some_variable
}

На жаль, Firebug оцінює таке твердження як помилку під час виконання, коли some_variableвоно не визначене, тоді як перший - це просто добре. Це лише (небажана) поведінка Firebug чи дійсно є якась різниця між цими двома способами?


46
if(some_variable) { ... }не виконується, якщо some_variableє falseабо 0...
kennytm

хороший пункт;) Але скажімо, я знаю, що це не може бути помилково або 0, і я просто хочу перевірити, чи можу я використовувати його в якійсь логіці (як рядок, масив тощо)
Томаш Вана,


2
... або порожній рядок.
Девід Даний

Відповіді:


333

Ви повинні розрізняти випадки:

  1. Змінні можуть бути undefinedабо незадекларовані . Ви отримаєте помилку, якщо отримаєте доступ до незадекларованої змінної в будь-якому іншому, крім typeof.
if(typeof someUndeclaredVar == whatever) // works
if(someUndeclaredVar) // throws error

Змінна, яка була оголошена, але не ініціалізована, є undefined.

let foo;
if (foo) //evaluates to false because foo === undefined
  1. Не визначені властивості , як someExistingObj.someUndefProperty. Невизначене властивість не видає помилки і просто повертається undefined, що при перетворенні в бульне значення оцінюється в false. Тож, якщо вам не байдуже, 0а falseвикористання if(obj.undefProp)- це нормально. На цьому факті є загальна ідіома:

    value = obj.prop || defaultValue

    що означає "якщо objмає властивість prop, призначте його value, інакше призначте значення за замовчуванням defautValue".

    Деякі люди вважають цю поведінку заплутаною, стверджуючи, що це призводить до важко знайти помилок, і рекомендують inзамість цього використовувати оператора

    value = ('prop' in obj) ? obj.prop : defaultValue

1
Тоді ви могли б поговорити про hasOwnProperty та прототипи. 'indexOf' в []! == [] .hasOwnProperty ('indexOf')
Alsciende,

1
Так, я думав над цим додати, але вирішив пожертвувати повнотою заради стислості. ;)
користувач187291

52
ви не вирішуєте проблему 0 та false
TMS

12
Ви маєте на увазі незадекларовані змінні. Змінна може бути оголошена, але все ще має значення undefined.
Тгр

1
А також зауважте, що typeofповертає рядок. Отже, не var myVar; typeof(myVar)==undefinedповертається . falsetrue
rism

417

Я думаю, що найефективніший спосіб перевірити на "значення є nullчи undefined" є

if ( some_variable == null ){
  // some_variable is either null or undefined
}

Отже, ці два рядки рівнозначні:

if ( typeof(some_variable) !== "undefined" && some_variable !== null ) {}
if ( some_variable != null ) {}

Примітка 1

Як було зазначено в питанні, короткий варіант вимагає, щоб some_variableце було оголошено, інакше буде викинуто ReferenceError. Однак у багатьох випадках використання можна припустити, що це безпечно:

перевірити наявність необов'язкових аргументів:

function(foo){
    if( foo == null ) {...}

перевірити властивості існуючого об'єкта

if(my_obj.foo == null) {...}

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

Примітка 2

Цей - ще коротший - варіант не рівнозначний:

if ( !some_variable ) {
  // some_variable is either null, undefined, 0, NaN, false, or an empty string
}

тому

if ( some_variable ) {
  // we don't get here if some_variable is null, undefined, 0, NaN, false, or ""
}

Примітка 3

Взагалі рекомендується використовувати ===замість ==. Пропоноване рішення є винятком із цього правила. Перевірки синтаксису JSHint навіть надає eqnullопцію з цієї причини.

З посібника зі стилю jQuery :

Суворі перевірки рівності (===) повинні використовуватися на користь ==. Єдиний виняток - це при перевірці на невизначеність та null шляхом null.

// Check for both undefined and null values, for some important reason. 
undefOrNull == null;

1
Дуже важлива відмінність (про яку вже йшлося у питанні btw). Тому всі використовують typeof. Вибачте, але я не знаю, де ваша відповідь корисна, ви просто зазначаєте те, що було сказано в питанні, і в перших кількох рядках ви заявляєте це навіть неправильно.
TMS

33
Вибачте, але я не погоджуюся ;-) Використання == nullimho є найбільш ефективним для тестування на "null or undefined" (це тема питань). Це аж ніяк не рідкість (використовується 43 рази в jQuery 1.9.1), оскільки дуже часто ви знаєте, що змінна була оголошена - або ви перевіряєте властивість існуючого об'єкта на зразок if( o.foo == null).
mar10,

1
@ mar10 (aUndefinedVar == null) дає помилку "aUndefinedVar не визначено" помилка не відповідає дійсності.
Раннн

7
Дякую за цей короткий варіант. У 99% мого коду немає необхідності розрізняти нульовий і невизначений, тому стислість цієї перевірки призводить до менш захаращеного коду.
Ian Lovejoy

1
Щоб запобігти ReferenceError під час перевірки глобальної змінної, використовуйте window.someProperty == null. Для локальних змінних, ви можете легко переконатися , що вони оголошені: замість написання if (...) {var local = ""}записуvar local; if (...) { local = ""; }
Aloso

66

Перевірка нуля при нормальній рівності також поверне справжнє для невизначеного.

if (window.variable == null) alert('variable is null or undefined');

Рівність JS


4
NaN не дорівнює Nan?
Шарджіл Ахмед

2
@monotheist NaN не дорівнює NaN (див . сторінку NaN MDN ). Javascript використовує IEEE-754 для своєї плаваючої точки, яка визначає цю поведінку. До цього є деякі думки, дивіться stackoverflow.com/a/23666623/2563765
Стівен

1
@SharjeelAhmed Це математично виправлено. NaNвід рівняння різниці ніколи не можна очікувати, що воно буде рівним
Таїна

28

У нових стандартах JavaScript, таких як ES5 та ES6, ви можете просто сказати

> Boolean(0) //false
> Boolean(null)  //false
> Boolean(undefined) //false

всі повертають false, що схоже на перевірку Python порожніх змінних. Тож якщо ви хочете написати умовну логіку навколо змінної, просто скажіть

if (Boolean(myvar)){
   // Do something
}

тут "null" або "порожній рядок" або "undefined" будуть оброблятися ефективно.


2
підтримується вниз на зразок ie5, чому це не більше відоме !?
Гімматори

12
ОП просто хотів перевірити різні nullі undefined, інші помилкові значення повинні повернути справжнє!
Andre Figueiredo

1
Це не додає значення умовно. Умова обчислюється точно так же і по- , як і раніше повертає брехня для 0, NaN. Це для тих випадків, коли ви хочете визначити правдивість об'єкта без збереження посилання на об'єкт, щоб ви могли зберігати його, а не якийсь потенційно великий об'єкт. У БЮІ це також еквівалентно тому !!value, що перший !заперечує правдивість, а другий знову його заперечує.
erich2k8

> FYI це також еквівалентно значенню !!, яке перше! заперечує правдивість. Який FYI також еквівалентний тому, if (var)що буде
передано булевим

2
Хоча буквально використовується ключове слово undefined , Boolean(undefined)працює, намагаючись, що з невизначеною змінною не працює, і в цьому вся справа в тому, щоб робити перевірку на null або undefined. Це: if (Boolean(undeclareVarName)) { console.log('yes'); } else { console.log('no'); }кидає ReferenceError, кажучи "ReferenceError: undeclareVarName не визначено"
Stephen P

22

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

Властивості об'єктів не підпадають під однакові умови. Якщо властивість об'єкта не визначена, помилка не буде видана, якщо ви спробуєте отримати доступ до неї. Тож у цій ситуації ви можете скоротити:

 if (typeof(myObj.some_property) != "undefined" && myObj.some_property != null)

до

if (myObj.some_property != null)

З огляду на це та факт, що глобальні змінні доступні як властивості глобального об’єкта ( windowу випадку браузера), ви можете використовувати наступне для глобальних змінних:

if (window.some_variable != null) {
    // Do something with some_variable
}

У локальних областях завжди корисно переконатися, що змінні оголошені у верхній частині кодового блоку, це дозволить заощадити на повторному використанні typeof.


11
Ви пропустите NaN, 0, "" і хибну причину, оскільки вони не є недійсними і не визначеними, але помилковими.
Andreas Köberle

@Andreas Köberle має рацію. Навіть оператор не строгої рівності каже, що null відрізняється від NaN, 0, "" і false. Вам доведеться зробити, if (myObj.some_property != null)щоб отримати рівнозначну поведінку.
thejoshwolfe

15

По-перше, ви повинні бути чітко зрозумілими, що ви протестуєте. У JavaScript є всілякі неявні конверсії, які дозволять вам подолати, та два різні типи порівняння рівності: ==і ===.

Функція, test(val)яка тестує для nullабо undefinedповинна мати такі характеристики:

 test(null)         => true
 test(undefined)    => true
 test(0)            => false
 test(1)            => false
 test(true)         => false
 test(false)        => false
 test('s')          => false
 test([])           => false

Подивимося, яка з ідей тут насправді проходить наш тест.

Ці роботи:

val == null
val === null || val === undefined
typeof(val) == 'undefined' || val == null
typeof(val) === 'undefined' || val === null

Вони не працюють:

typeof(val) === 'undefined'
!!val

Я створив запис jsperf, щоб порівняти правильність та ефективність цих підходів. Наразі результати є непереконливими, оскільки недостатньо пробігів у різних браузерах / платформах. Будь ласка, знайдіть хвилину, щоб запустити тест на своєму комп’ютері!

В даний час здається, що простий val == nullтест дає найкращі показники. Це також майже найкоротший. val != nullЯкщо ви хочете доповнити, тест може бути відхилений .


12

це єдиний випадок, коли ==слід використовувати:

if (val == null) console.log('val is null or undefined')

3
ця відповідь є приблизно у 2019 році, але вона є недооціненою, але це KISS для цього випадку використання. Крім val != nullтого, навпаки, лише один, = і оскільки на @ Yukulele це ТІЛЬКИЙ для використання, ==ви знаєте, що робить, коли ви його бачите.
DKebler

7

Оскільки єдиної повної та правильної відповіді немає, спробую підсумувати:

Загалом, вираз:

if (typeof(variable) != "undefined" && variable != null)

не може бути спрощено, тому що variableможе бути недекларовано, тому пропускання цього typeof(variable) != "undefined"призведе до ReferenceError. Але ви можете спростити вираз відповідно до контексту :

Якщо variableце глобальний , ви можете спростити:

if (window.variable != null)

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

if (variable != null)

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

if (obj.property != null)

Є navigatorчастиною window? Коли ми отримуємо виняток для navigator is not defined, чи можемо ми використати window.navigator != nullтест?
jww

5

Ви можете просто перевірити, чи має змінна значення чи ні. Значення,

if( myVariable ) {
//mayVariable is not :
//null
//undefined
//NaN
//empty string ("")
//0
//false

}

Якщо ви не знаєте, чи існує змінна (це означає, якщо вона була задекларована), слід звернутися до оператора typeof. напр

if( typeof myVariable !== 'undefined' ) {
    // myVariable will get resolved and it is defined
}

4

Я зробив це за допомогою цього методу

збережіть ідентифікатор у деякій змінній

var someVariable = document.getElementById("someId");

тоді використовуйте, якщо умова

if(someVariable === ""){
 //logic
} else if(someVariable !== ""){
 //logic
}

3

Як згадується в одній з відповідей, ви можете пощастити, якщо ви будете говорити про змінну, яка має глобальну сферу застосування. Як ви можете знати, змінні, які ви визначаєте в усьому світі, як правило, додаються до об’єкта Windows. Ви можете скористатися цим фактом, тому скажемо, що ви отримуєте доступ до змінної під назвою bleh, просто використовуйте подвійний перевернутий оператор (!!)

!!window['bleh'];

Це поверне помилкове значення, поки bleh не було оголошено ТА присвоєно значення.


3

ось ще один спосіб використання методу Array include () :

[undefined, null].includes(value)

Це не працює! ReferenceError: значення не визначено
Sébastien Temprado

1
Це має бути значення, яке ви хочете перевірити.
a2441918

2

незалежно ууу не визначений або порожній, вона повертає істину

if (typeof yyy == 'undefined' || !yyy) {
    console.log('yes');
} else {
    console.log('no');
}

так

if (!(typeof yyy == 'undefined' || !yyy)) {
    console.log('yes');
} else {
    console.log('no');
}

ні


2

Відкрийте інструменти розробника у своєму браузері та просто спробуйте код, показаний на зображенні нижче.

Img1 Img2


2

Для того, щоб зрозуміти, давайте проаналізуємо, що буде поверненням значення Javascript Engine при перетворенні невизначених, null і '' (також порожній рядок). Ви можете безпосередньо перевірити те саме на консолі розробника.

введіть тут опис зображення

Ви можете бачити, що всі перетворюються на помилкові, значить, всі ці три припускають, що JavaScript не існує. Тож вам не потрібно чітко перевіряти всі три у своєму коді, як показано нижче.

if (a === undefined || a === null || a==='') {
    console.log("Nothing");
} else {
    console.log("Something");
}

Також хочу зазначити ще одне.

Яким буде результат Булева (0)?

Звичайно хибні. Це створить помилку у вашому коді, коли 0 - дійсне значення у вашому очікуваному результаті. Тому, будь ласка, переконайтеся, що ви це перевіряєте, коли пишете код.


2

Подібно до того, що у вас є, ви могли зробити щось подібне

if (some_variable === undefined || some_variable === null) { do stuff }


2

Це приклад дуже рідкісного випадку, коли його рекомендується використовувати ==замість ===. Вираз somevar == nullповернеться true для undefinedта null, але false для всього іншого (помилка, якщо змінна не буде оголошена).

Використовуючи !=волю, перегорне результат, як очікувалося.

Сучасні редактори не попередитимуть про використання ==чи !=оператор null, оскільки це майже завжди бажана поведінка.

Найпоширеніші порівняння:

undeffinedVar == null     // true
obj.undefinedProp == null // true
null == null              // true
0 == null                 // false
'0' == null               // false
'' == null                // false

Спробуйте самі:

let undefinedVar;
console.table([
    { test : undefinedVar,     result: undefinedVar     == null },
    { test : {}.undefinedProp, result: {}.undefinedProp == null },
    { test : null,             result: null             == null },
    { test : false,            result: false            == null },
    { test : 0,                result: 0                == null },
    { test : '',               result: ''               == null },
    { test : '0',              result: '0'              == null },
]);

0

Тестування nullity ( if (value == null)) або non-nullity ( if (value != null)) є менш дослідним, ніж тестування статусу визначення змінної.

Більше того, тестування if (value)(або if( obj.property)) для забезпечення існування вашої змінної (або властивості об'єкта) не вдається, якщо вона визначена з булевим falseзначенням. Caveat emptor :)


0

Обидва значення можна легко відрізнити за допомогою оператора суворого порівняння:

Приклад роботи за адресою:

http://www.thesstech.com/tryme?filename=nullandundefined

Приклад коду:

function compare(){
    var a = null; //variable assigned null value
    var b;  // undefined
    if (a === b){
        document.write("a and b have same datatype.");
    }
    else{
        document.write("a and b have different datatype.");
    }   
}

0

Якщо метою оператора if є перевірка значень nullабо undefinedзначень перед присвоєнням значення змінній, ви можете скористатися Nullish Coalescing Operator , нарешті доступний на JavaScript, хоча підтримка браузера обмежена. За даними каніуси підтримується лише 48,34% браузерів (станом на квітень 2020 року).

const a = some_variable ?? '';

Це забезпечить, що змінна буде присвоєна порожній рядку (або будь-якому іншому за замовчуванням), якщо some_variableє nullабо undefined.

Цей оператор найбільше підходить для вашого випадку використання, оскільки він не повертає значення за замовчуванням для інших типів фальшивого значення, таких як 0і ''.


-1

Ви повинні визначити функцію цієї форми:

validate = function(some_variable){
    return(typeof(some_variable) != 'undefined' && some_variable != null)
}

Це створить той самий ReferenceError, якщо змінна не буде оголошена.
Чад

-1

У ES5 або ES6, якщо вам потрібно перевірити це кілька разів:

const excluded = [null, undefined, ''];

if (!exluded.includes(varToCheck) {
  // it will bee not null, not undefined and not void string
}


-1

З Рамдою ви можете просто зробити R.isNil(yourValue) Лодаша, а інші бібліотеки-помічники мають ту саму функцію.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.