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