переменная === неопределено и переменную для вызова 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, этот тип проверки никогда не выполняется, потому что если он не существует, он не будет компилироваться.


typeof a === 'undefined' затем быстрее a === 'undefined' примерно в 2 раза на узле v6.9.1.