переменная === неопределенная или переменная typeof === "неопределенная" - PullRequest
274 голосов
/ 18 января 2011

Руководство по стилю ядра jQuery предлагает два различных способа проверки определения переменной.

  • Глобальные переменные: typeof variable === "undefined"
  • Локальные переменные: variable === undefined
  • Свойства: object.prop === undefined

Почему jQuery использует один подход для глобальных переменных, а другой - для локальных переменных и свойств?

Ответы [ 8 ]

329 голосов
/ 18 января 2011

Для необъявленных переменных typeof foo вернет строковый литерал "undefined", тогда как проверка идентичности foo === undefined вызовет ошибку "foo is notfined" .

локальные переменные (которые вы знаете, объявлены где-то), такой ошибки не возникнет, следовательно, проверка идентичности.

110 голосов
/ 18 января 2011

Я бы использовал typeof foo === "undefined" везде.Это никогда не может пойти не так.

Я предполагаю, что jQuery рекомендует два различных метода в том, что они определяют свою собственную переменную undefined в функции, в которой находится код jQuery, поэтому внутри этой функции undefinedв безопасности от вмешательства извне.Я также предположил бы, что кто-то где-то сравнил два разных подхода и обнаружил, что foo === undefined быстрее, и поэтому решил, что это путь. [ОБНОВЛЕНИЕ: как отмечено в комментариях, сравнение с undefined также немного короче, что может быть соображением.] Однако выигрыш в практических ситуациях будет крайне незначительным: эта проверка никогда не будет,когда-либо становиться узким местом, и то, что вы потеряете, важно: оценка свойства хост-объекта для сравнения может вызвать ошибку, тогда как проверка typeof никогда не будет.

Например, следующее используется вIE для синтаксического анализа XML:

var x = new ActiveXObject("Microsoft.XMLDOM");

Чтобы безопасно проверить, есть ли у него метод loadXML:

typeof x.loadXML === "undefined"; // Returns false

С другой стороны:

x.loadXML === undefined; // Throws an error

UPDATE

Еще одно преимущество проверки typeof, о которой я забыл упомянуть, заключалось в том, что она также работает с необъявленными переменными, чего нет у проверки foo === undefined, и фактически выдает ReferenceError.Спасибо @LinusKleen за напоминание.Например:

typeof someUndeclaredVariable; // "undefined"
someUndeclaredVariable === undefined; // throws a ReferenceError

Итог: всегда используйте проверку typeof.

26 голосов
/ 18 января 2011

Еще одна причина использования typeof-варианта: undefined может быть переопределено.

undefined = "foo";
var variable = "foo";
if (variable === undefined)
  console.log("eh, what?!");

Результат typeof variable не может.

Обновление : обратите внимание, что в ES5 это не так.

6 голосов
/ 19 февраля 2014

Кто заинтересован в увеличении производительности variable === undefined, может посмотреть здесь, но, похоже, это только оптимизация Chrome.

6 голосов
/ 18 января 2011

Поскольку undefined не всегда объявляется, но jQuery объявляет undefined в своей основной функции. Поэтому они используют безопасное значение undefined внутри, но снаружи они используют стиль typeof для обеспечения безопасности.

1 голос
/ 08 декабря 2018

Резюме:

Когда в глобальной области мы действительно хотим вернуть true, если переменная не объявлена ​​или имеет значение undefined:

var globalVar1;

// This variable is declared, but not defined and thus has the value undefined
console.log(globalVar1 === undefined);

// This variable is not declared and thus will throw a referenceError
console.log(globalVar2 === undefined);

Поскольку в глобальной области мы не уверены на 100%, если объявлена ​​переменная, это может дать нам referenceError. Когда мы используем оператор typeof для неизвестной переменной, мы не получаем эту проблему, когда переменная не объявлена:

var globalVar1;

console.log(typeof globalVar1 === 'undefined');
console.log(typeof globalVar2 === 'undefined');

Это связано с тем, что оператор typeof возвращает строку undefined, когда переменная не объявлена ​​или в настоящее время содержит значение undefined, которое является именно тем, что мы хотим.


  • С локальными переменными у нас нет этой проблемы, потому что мы заранее знаем, что эта переменная будет существовать. Мы можем просто посмотреть в соответствующей функции, если переменная присутствует.
  • Со свойствами объекта у нас нет этой проблемы, потому что, когда мы пытаемся найти свойство объекта, которое не существует, мы также получаем значение undefined

var obj = {};

console.log(obj.myProp === undefined);
1 голос
/ 09 октября 2017

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

<== Fiddle Me ==>

0 голосов
/ 22 мая 2017

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

...