Каков наиболее подходящий способ проверить, есть ли переменная undefined в JavaScript? Я видел несколько возможных способов:
if (window.myVariable)
или
if (typeof(myVariable) != "undefined")
или
if (myVariable) //This throws an error if undefined. Should this be in Try/Catch?
Если вам интересно узнать, была ли указана переменная независимо от ее значения, то использование оператора 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')
Оператору typeof
гарантируется возврат строки. Прямые сравнения с undefined
являются неудобными, поскольку undefined
могут быть перезаписаны.
window.undefined = "omg";
"omg" == undefined // true
Как отмечала @CMS, это было исправлено в ECMAScript 5th ed., А undefined
не записывается.
if (window.myVar)
также будет включать эти значения фальши, поэтому он не очень устойчив:
false 0 "" NaN null undefined
Благодаря @CMS за то, что ваш третий случай - if (myVariable)
также может if (myVariable)
ошибку в двух случаях. Во-первых, когда переменная не определена, которая вызывает ReferenceError
.
// abc was never declared.
if (abc) {
// ReferenceError: abc is not defined
}
Другой случай - когда переменная определена, но имеет функцию геттера, которая вызывает ошибку при вызове. Например,
// or it a property that can throw an error
Object.defineProperty(window, "myVariable", {
get: function() { throw new Error("W00t?"); },
set: undefined
});
if (myVariable) {
// Error: W00t?
}
ReferenceError
если myVariable
не объявлена ...
myVariable
был объявлен где-то, просто без значения.
Я лично использую
myVar === undefined
Внимание: обратите внимание, что ===
используется над ==
и что myVar
ранее объявлен (не определен).
Мне не нравится typeof myVar === "undefined"
. Я думаю, что он длинный и ненужный. (Я могу сделать то же самое в меньшем коде.)
Теперь некоторые люди будут кипеть от боли, когда они прочтут это, крича: "Подождите! WAAITTT!!! undefined
можно переопределить!"
Круто. Я знаю это. Опять же, большинство переменных в Javascript можно переопределить. Если вы никогда не используете встроенный идентификатор, который можно переопределить?
Если вы будете следовать этому правилу, хорошо для вас: вы не лицемер.
Дело в том, что для того, чтобы делать много реальной работы в JS, разработчикам нужно полагаться на переопределяемые идентификаторы, чтобы быть тем, кем они являются. Я не слышу, как люди говорят мне, что я не должен использовать setTimeout
, потому что кто-то может
window.setTimeout = function () {
alert("Got you now!");
};
Нижняя строка, аргумент "он может быть переопределен", чтобы не использовать raw === 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
(и **** cough **** typeof
) работает отлично. Если вам действительно все равно, вы может прочитать об этом предмете самостоятельно.)
undefined
может быть переопределен только потому, что люди используют его для таких проверок. Некоторые люди обычно ставят константу слева при выполнении таких проверок: if (undefined == someVariable)
. Для этого требуется только опечатка, чтобы молча переопределить undefined
: if (undefined = someVariable)
.
undefined
на LHS. Даже если бы я это сделал, тот факт, что я использую ===
вместо ==
делает опечатку крайне маловероятной. Но тот факт, что ==
неверно, больше беспокоит. В любом случае, подобную ошибку обычно легко найти. typeof x == "undefned"
как эта ошибка: typeof x == "undefned"
.
Использование typeof
- мое предпочтение. Он будет работать, когда переменная никогда не была объявлена, в отличие от любого сравнения с операторами ==
или ===
или типом принуждения с использованием if
. (undefined
, в отличие от null
, также может быть переопределено в средах ECMAScript 3, что делает его ненадежным для сравнения, хотя почти все обычные среды теперь совместимы с ECMAScript 5 или выше).
if (typeof someUndeclaredVariable == "undefined") {
// Works
}
if (someUndeclaredVariable === undefined) {
// Throws an error
}
Вам нужно использовать typeof
.
if (typeof something != "undefined") {
// ...
}
something !== undefined
, если вы уже сделали var undefined
, предварительно осторожно.
!==
) в этом случае не требуется, так как typeof
всегда будет возвращать строку.
Если это undefined, он не будет равен строке, содержащей символы "undefined", поскольку строка не undefined.
Вы можете проверить тип переменной:
if (typeof(something) != "undefined") ...
Иногда вам даже не нужно проверять тип. Если значение переменной не может быть оценено в false, когда оно установлено (например, если это функция), вы можете просто оценить переменную. Пример:
if (something) {
something(param);
}
typeof
является оператором, а не функцией.
Некоторые сценарии, иллюстрирующие результаты различных ответов: 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
undefined
в undefined
области видимости; это не только защищает от (необычного) случая «о, но undefined
может быть переопределено», но также «помогает» в минификации.
if (typeof foo == 'undefined') {
// Do something
};
Обратите внимание, что в этом случае не требуется строгое сравнение (!==
), так как typeof
всегда будет возвращать строку.
};
)?
В в этой статье Я читал, что фреймворки, такие как Underscore.js используйте эту функцию:
function isUndefined(obj){
return obj === void 0;
}
Прошло почти пять лет с момента создания этого сообщения, и JavaScript прошел долгий путь. Повторяя тесты в исходном посте, я не нашел постоянной разницы между следующими методами тестирования:
abc === undefined
abc === void 0
typeof abc == 'undefined'
typeof abc === 'undefined'
Даже когда я модифицировал тесты, чтобы предотвратить их оптимизацию, различия были незначительными. Поэтому я бы рекомендовал abc === undefined
для ясности.
Соответствующий контент из chrome://version
:
В Google Chrome, следующий был чуть - чуть быстрее, чем typeof
тест:
if (abc === void 0) {
// Undefined
}
Разница была незначительной. Однако этот код является более кратким и более ясным с точки зрения того, кто знает, что означает void 0
. Обратите внимание, однако, что abc
все равно должен быть объявлен.
Оба typeof
и void
были значительно быстрее, чем сравнение непосредственно с undefined
. Я использовал следующий тестовый формат в консоли разработчика Chrome:
var abc;
start = +new Date();
for (var i = 0; i < 10000000; i++) {
if (TEST) {
void 1;
}
}
end = +new Date();
end - start;
Результаты были следующими:
Test: | abc === undefined abc === void 0 typeof abc == 'undefined'
------+---------------------------------------------------------------------
x10M | 13678 ms 9854 ms 9888 ms
x1 | 1367.8 ns 985.4 ns 988.8 ns
Обратите внимание, что первая строка находится в миллисекундах, а вторая - в наносекундах. Разница в 3,4 наносекунды - ничто. Время было довольно последовательным в последующих тестах.
===
для проверки undefined
!
void 0
звучит более необычно для меня, 2) вместо этого вы должны поделиться своими тестами перфоратора , но в основном 3) ваш первый пример ( abc === void 0
) выдает исключение, если abc
не определено.
Самый надежный способ проверки undefined
- использовать void 0
.
Это совместимо с более старыми и более старыми браузерами и не может быть перезаписано, например, как window.undefined
.
if( myVar === void 0){
//yup it undefined
}
undefined !== void 0
, у вас, вероятно, есть другие серьезные проблемы в указанной кодовой базе.
Лично я всегда использую следующее:
var x;
if( x === undefined) {
//Do something here
}
else {
//Do something else here
}
Свойство window.undefined не доступно для записи во всех современных браузерах (JavaScript 1.8.5 или новее). Из документации Mozilla: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined, я вижу следующее: Одна из причин использования typeof() заключается в том, что она не выдает ошибку, если переменная имеет не определено.
Я предпочитаю использовать подход
x === undefined
потому что он терпит неудачу и взрывается в моем лице, а не бесшумно проходит/терпит неудачу, если x не был объявлен ранее. Это предупреждает меня, что x не объявлен. Я считаю, что все переменные, используемые в JavaScript, должны быть объявлены.
undefined
используя контекстные оболочки: (function($, undefined){ /* undefined is 'abc' in here */ })(jQuery, 'abc');
Вот почему пользователи жалуются на то, что это технически небезопасно, если вы не уверены на 100%, что знаете, где выполняется ваш код.
Поскольку ни один из ответов не помог мне, я предлагаю сделать это. Это работало для меня в Internet Explorer 8:
if (typeof variable_name.value === 'undefined') {
// variable_name is undefined
}
// x has not been defined before
if (typeof x === 'undefined') { // Evaluates to true without errors.
// These statements execute.
}
if (x === undefined) { // Throws a ReferenceError
}
Напротив ответа @Thomas Eding:
Если я забыл объявить myVar
в своем коде, тогда я получу myVar is not defined
.
Возьмем реальный пример:
У меня есть имя переменной, но я не уверен, что она объявлена где-то или нет.
Затем ответ @Anurag поможет:
var myVariableToCheck = 'myVar';
if (window[myVariableToCheck] === undefined)
console.log("Not declared or declared, but undefined.");
// Or you can check it directly
if (window['myVar'] === undefined)
console.log("Not declared or declared, but undefined.");
myVar is not defined
ошибка будет хорошей вещью, особенно если вы специально напишите «Если я забуду объявить» [выделено мной]. Мне нравится, когда я получаю ошибки до запуска моего кода. Если вы хотите узнать больше моего мнения о вашем ответе, я сделал соответствующие комментарии под моим ответом.
var x;
if (x === undefined) {
alert ("I am declared, but not defined.")
};
if (typeof y === "undefined") {
alert ("I am not even declared.")
};
/* One more thing to understand: typeof ==='undefined' also checks
for if a variable is declared, but no value is assigned. In other
words, the variable is declared, but not defined. */
// Will repeat above logic of x for typeof === 'undefined'
if (x === undefined) {
alert ("I am declared, but not defined.")
};
/* So typeof === 'undefined' works for both, but x === undefined
only works for a variable which is at least declared. */
/* Say if I try using typeof === undefined (not in quotes) for
a variable which is not even declared, we will get run a
time error. */
if (z === undefined) {
alert ("I am neither declared nor defined.")
};
// I got this error for z ReferenceError: z is not defined
Я использую его как параметр функции и исключаю его при выполнении функции таким образом, что получаю "реальный" undefined. Хотя это требует, чтобы вы включили код внутри функции. Я нашел это при чтении источника jQuery.
undefined = 2;
(function (undefined) {
console.log(undefined); // prints out undefined
// and for comparison:
if (undeclaredvar === undefined) console.log("it works!")
})()
Конечно, вы могли бы просто использовать typeof
. Но весь мой код обычно находится внутри содержащейся функции, поэтому использование этого метода, вероятно, сэкономит мне несколько байтов здесь и там.
var undeclaredvar = window.someUndeclaredVar; if (undeclaredvar === undefined) console.log("it works!").
Пожалуйста, проверьте ваш пример перед публикацией.
undefined
илиnull
?