переменная === неопределено и переменную для вызова typeof === "не определено"
на основные принципы стиля jQuery предложите два разных способа проверить, определена ли переменная.
- Глобальные Переменные:
typeof variable === "undefined"
- Локальные Переменные:
variable === undefined
- свойства:
object.prop === undefined
почему jQuery использует один подход для глобальных переменных, а другой для локальных и свойств?
7 ответов
для необъявленных переменных,typeof foo
возвращает строковый литерал "undefined"
, тогда как проверка документов foo === undefined
вызовет ошибку "foo не определен".
для локальных переменных (которые знаю где-то объявлены), такой ошибки не произойдет, следовательно, проверка личности.
я бы придерживался использования typeof foo === "undefined"
везде. Это никогда не может пойти не так.
Я предполагаю, что причина, по которой jQuery рекомендует два разных метода, заключается в том, что они определяют свои собственные undefined
переменная внутри функции, в которой живет код jQuery, поэтому внутри этой функции undefined
защищен от вмешательства извне. Я бы также предположил, что кто-то где-то сравнил два разных подхода и обнаружил, что foo === undefined
быстрее и поэтому решил, что это путь. [UPDATE: как отмечено в комментариях, сравнение с undefined
также немного короче, что может быть рассмотрением.] однако выигрыш в практических ситуациях будет совершенно незначительным: эта проверка никогда не будет каким-либо узким местом, и то, что вы теряете, является значительным: оценка свойства объекта хоста для сравнения может вызвать ошибку, тогда как typeof
проверка никогда не будет.
например, в IE для синтаксического анализа используется следующее XML-код:
var x = new ActiveXObject("Microsoft.XMLDOM");
чтобы проверить, имеет ли он loadXML
способ безопасно:
typeof x.loadXML === "undefined"; // Returns false
С другой стороны:
x.loadXML === undefined; // Throws an error
обновление
еще одно преимущество typeof
проверьте, что я забыл упомянуть, что он также работает с необъявленными переменными, которые foo === undefined
регистрация не дает, а на самом деле бросает!--13-->. Спасибо @LinusKleen за напоминание. Например:
typeof someUndeclaredVariable; // "undefined"
someUndeclaredVariable === undefined; // throws a ReferenceError
нижняя строка: всегда используйте typeof
проверка.
еще одна причина использования typeof-variant:undefined
можно переопределить.
undefined = "foo";
var variable = "foo";
if (variable === undefined)
console.log("eh, what?!");
результат typeof variable
не может.
обновление: обратите внимание, что это не так в ES5.
кто заинтересован в увеличении производительности variable === undefined
, может взглянуть здесь, но, похоже, это только оптимизация chrome.
, потому что undefined
не всегда объявляется, но jQuery объявляет undefined
в своей основной функции. Поэтому они используют сейф undefined
значение внутренне, но снаружи, они используют typeof
стиль, чтобы быть безопасным.
для локальных переменных, проверки с localVar === undefined
будет работать, потому что они должны быть определены где-то в локальной области или они не будут считаться местными.
для переменных, которые не являются локальными и не определены нигде, проверка someVar === undefined
выбросит исключение:Uncaught ReferenceError: j не определен
вот некоторый код, который прояснит то, что я говорю выше. Пожалуйста, обратите внимание на встроенные комментарии для дальнейшей ясность.
function f (x) {
if (x === undefined) console.log('x is undefined [x === undefined].');
else console.log('x is not undefined [x === undefined.]');
if (typeof(x) === 'undefined') console.log('x is undefined [typeof(x) === \'undefined\'].');
else console.log('x is not undefined [typeof(x) === \'undefined\'].');
// This will throw exception because what the hell is j? It is nowhere to be found.
try
{
if (j === undefined) console.log('j is undefined [j === undefined].');
else console.log('j is not undefined [j === undefined].');
}
catch(e){console.log('Error!!! Cannot use [j === undefined] because j is nowhere to be found in our source code.');}
// However this will not throw exception
if (typeof j === 'undefined') console.log('j is undefined (typeof(x) === \'undefined\'). We can use this check even though j is nowhere to be found in our source code and it will not throw.');
else console.log('j is not undefined [typeof(x) === \'undefined\'].');
};
если мы вызовем вышеуказанный код следующим образом:
f();
вывод будет следующим:
x is undefined [x === undefined].
x is undefined [typeof(x) === 'undefined'].
Error!!! Cannot use [j === undefined] because j is nowhere to be found in our source code.
j is undefined (typeof(x) === 'undefined'). We can use this check even though j is nowhere to be found in our source code and it will not throw.
если мы вызовем вышеуказанный код, как эти (с любым значением на самом деле):
f(null);
f(1);
выход будет:
x is not undefined [x === undefined].
x is not undefined [typeof(x) === 'undefined'].
Error!!! Cannot use [j === undefined] because j is nowhere to be found in our source code.
j is undefined (typeof(x) === 'undefined'). We can use this check even though j is nowhere to be found in our source code and it will not throw.
когда вы делаете проверку, как это:typeof x === 'undefined'
, вы по сути спрашиваете: пожалуйста, проверьте, если переменная x
существует (было определено) где-то в источнике код. (более или менее). Если вы знаете C# или Java, этот тип проверки никогда не выполняется, потому что если он не существует, он не будет компилироваться.