JavaScript null check

Я натолкнулся на следующий код:

function (data) {
    if (data != null && data !== undefined) {
        // some code here
    }
}

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


В частности, этот ответ гласит, что Дел >

Вы получите сообщение об ошибке при доступе к переменной undefined в любом контексте, отличном от typeof.Дел >

Обновление: Ответ (цитата) выше может ввести в заблуждение. Он должен сказать "необъявленную переменную" вместо "a undefined variable".

Как я узнал в ответах Ryan ♦, maerics и nwellnhof, даже если аргументы не передаются функции, его переменные для аргументов всегда объявляются. Этот факт также не соответствует первому элементу в списке ниже.


По моему мнению, могут возникнуть следующие сценарии:

  • Функция вызывалась без аргументов, тем самым делая data переменную undefined и поднимая ошибку на data != null.

  • Функция была вызвана специально с помощью null (или undefined) в качестве аргумента, и в этом случае data != null уже защищает внутренний код, рендеринг && data !== undefined бесполезен.

  • Функция вызывается с ненулевым аргументом, и в этом случае она будет тривиально проходить как data != null , так и data !== undefined.

Q: Правильно ли мое понимание?


В консоли Firefox я пробовал следующее:

--
[15:31:31.057] false != null
[15:31:31.061] true
--
[15:31:37.985] false !== undefined
[15:31:37.989] true
--
[15:32:59.934] null != null
[15:32:59.937] false
--
[15:33:05.221] undefined != null
[15:33:05.225] false
--
[15:35:12.231] "" != null
[15:35:12.235] true
--
[15:35:19.214] "" !== undefined
[15:35:19.218] true

Я не могу понять случай, когда data !== undefined после data != null может быть полезен.

Ответ 1

An "undefined variable" отличается от значения undefined.

Переменная undefined:

var a;
alert(b); // ReferenceError: b is not defined

Переменная со значением undefined:

var a;
alert(a); // Alerts "undefined"

Когда функция принимает аргумент, этот аргумент всегда объявляется, даже если его значение undefined, и поэтому не будет никакой ошибки. Вы правы в != null, а затем !== undefined бесполезны.

Ответ 2

В JavaScript null - специальный одноэлементный объект, который полезен для сигнализации "нет значения". Вы можете протестировать его для сравнения и, как обычно, в JavaScript, рекомендуется использовать оператор ===, чтобы избежать путаницы в типе:

var a = null;
alert(a === null); // true

Как упоминает @rynah, "undefined" немного запутан в JavaScript. Тем не менее, всегда безопасно проверять, является ли typeof(x) строка "undefined", даже если "x" не является объявленной переменной:

alert(typeof(x) === 'undefined'); // true

Кроме того, переменные могут иметь значение "undefined", если они не инициализированы:

var y;
alert(typeof(y) === 'undefined'); // true

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

if ((typeof(data) !== 'undefined') && (data !== null)) {
  // ...

Однако, поскольку переменная "данные" всегда определена, поскольку она является формальным параметром функции, использование оператора "typeof" не является необходимым, и вы можете смело сравнивать напрямую с "undefined value".

function(data) {
  if ((data !== undefined) && (data !== null)) {
    // ...

Этот фрагмент означает "если функция была вызвана с аргументом, который определен и не является нулевым..."

Ответ 3

Q: Функция вызывается без аргументов, поэтому данные undefined изменяются и возникают ошибки в данных!= null.

A: Да, data будет установлен на undefined. См. раздел 10.5 "Активация связывания с подписью" спецификации. Но доступ к значению undefined не вызывает ошибки. Вероятно, вы путаете это с доступом к необъявленной переменной в строгом режиме, которая вызывает ошибку.

Q: Функция была вызвана специально с нулевым (или undefined) в качестве аргумента, и в этом случае данные!= null уже защищают внутренний код, рендеринг && & data! == undefined бесполезно.

Q: Функция вызывается с ненулевым аргументом, и в этом случае она будет тривиально передавать оба данных: = null и данные! == undefined.

A: Исправить. Обратите внимание, что следующие тесты эквивалентны:

data != null
data != undefined
data !== null && data !== undefined

См. раздел 11.9.3 Алгоритм сравнения абстрактного равенства и раздел 11.9.6 Алгоритм сравнения строгого равенства спецификации.

Ответ 4

typeof foo === "undefined" отличается от foo === undefined, никогда не путайте их. typeof foo === "undefined" - это то, что вам действительно нужно. Кроме того, используйте !== вместо !=

Таким образом, оператор можно записать как

function (data) {
  if (typeof data !== "undefined" && data !== null) {
    // some code here
  }
}

Edit:

Вы не можете использовать foo === undefined для необъявленных переменных.

var t1;

if(typeof t1 === "undefined")
{
  alert("cp1");
}

if(t1 === undefined)
{
  alert("cp2");
}

if(typeof t2 === "undefined")
{
  alert("cp3");
}

if(t2 === undefined) // fails as t2 is never declared
{
  alert("cp4");
}

Ответ 5

Я думаю, что тестирование переменных для значений, которые вы не ожидаете, не является хорошей идеей в целом. Поскольку тест как ваш, вы можете рассматривать как запись черного списка запрещенных значений. Но что, если вы забыли перечислить все запрещенные значения? Кто-то, даже вы, может взломать свой код с передачей неожиданного значения. Таким образом, более подходящий подход - это что-то вроде whitelisting - тестирование переменных только для ожидаемых значений, а не неожиданно. Например, если вы ожидаете, что значение данных будет строкой, вместо этого:

function (data) {
  if (data != null && data !== undefined) {
    // some code here
    // but what if data === false?
    // or data === '' - empty string?
  }
}

сделайте что-нибудь вроде этого:

function (data) {
  if (typeof data === 'string' && data.length) {
    // consume string here, it is here for sure
    // cleaner, it is obvious what type you expect
    // safer, less error prone due to implicit coercion
  } 
}

Ответ 6

Простой способ выполнить ваш тест:

function (data) {
    if (data) { // check if null, undefined, empty ...
        // some code here
    }
}

Ответ 7

var a;
alert(a); //Value is undefined

var b = "Volvo"; 
alert(b); //Value is Volvo

var c = null;
alert(c); //Value is null