JavaScript: undefined! == undefined?

ПРИМЕЧАНИЕ. Согласно ECMAScript5.1, раздел 15.1.1.3, window.undefined доступен только для чтения.

  • Современные браузеры реализуют это правильно. например: Safari 5.1, Firefox 7, Chrome 20 и т.д.
  • Undefined по-прежнему меняется: Chrome 14,...

Когда я недавно интегрировал Facebook Connect с Tersus, Я сначала получил сообщения об ошибках Invalid Enumeration Value и Handler already exists при попытке вызвать функции Facebook API.

Оказалось, что причиной проблемы было

object.x === undefined

возвращает false, когда в 'объекте' нет свойства 'x'.

Я работал над проблемой, заменив строгое равенство регулярным равенством в двух функциях Facebook:

FB.Sys.isUndefined = function(o) { return o == undefined;};
FB.Sys.containsKey = function(d, key) { return d[key] != undefined;};

Это заставило меня работать, но, похоже, намекает на какое-то столкновение между кодом JavaScript Facebook и моим собственным.

Что может быть причиной этого?

Подсказка: хорошо документировано, что undefined == null пока undefined !== null. Здесь не проблема. Вопрос в том, как мы получаем undefined !== undefined.

Ответ 1

Оказывается, вы можете установить window.undefined на все, что хотите, и поэтому получите object.x !== undefined, когда object.x является реальным undefined. В моем случае я непреднамеренно установил undefined в null.

Самый простой способ увидеть это:

window.undefined = null;
alert(window.xyzw === undefined); // shows false

Конечно, этого маловероятно. В моем случае ошибка была немного более тонкой и была эквивалентна следующему сценарию.

var n = window.someName; // someName expected to be set but is actually undefined
window[n]=null; // I thought I was clearing the old value but was actually changing window.undefined to null
alert(window.xyzw === undefined); // shows false

Ответ 2

Проблема заключается в том, что undefined по сравнению с null использованием == дает true. Таким образом, общая проверка для undefined выполняется следующим образом:

typeof x == "undefined"

это гарантирует, что тип переменной действительно undefined.

Ответ 3

Я хочу опубликовать важную информацию о undefined, которую новички могут не знать.

Посмотрите на следующий код:

 /* 
  * Consider there is no code above. 
  * The browser runs these lines only.
  */

   // var a;  
   // --- commented out to point that we've forgotten to declare `a` variable 

   if ( a === undefined ) {
       alert('Not defined');
   } else {
       alert('Defined: ' + a);
   }

   alert('Doing important job below');

Если вы запустите этот код, где переменная a НИКОГДА НЕ ДЕЛАЕТСЯ, используя var, вы получите ИСКЛЮЧЕНИЕ ОШИБКИ и удивительно не увидите никаких предупреждений.

Вместо "Выполнение важной работы ниже" ваш script НЕИСПРАВЛЯЕТСЯ НЕПРЕРЫВНО, бросая необработанное исключение в самой первой строке.


Вот единственный пуленепробиваемый способ проверить undefined с помощью ключевого слова typeof, которое было разработано именно для этой цели:

   /* 
    * Correct and safe way of checking for `undefined`: 
    */

   if ( typeof a === 'undefined' ) {
       alert(
           'The variable is not declared in this scope, \n' +
           'or you are pointing to unexisting property, \n' +
           'or no value has been set yet to the variable, \n' + 
           'or the value set was `undefined`. \n' +
           '(two last cases are equivalent, don\'t worry if it blows out your mind.'
           );
   }

   /* 
    *  Use `typeof` for checking things like that
    */

Этот метод работает во всех возможных случаях.

Последний аргумент, используемый для использования, заключается в том, что undefined может быть потенциально перезаписан в более ранних версиях Javascript:

     /* @ Trollface @ */
        undefined = 2;
     /* Happy debuging! */  

Надеюсь, я был достаточно ясен.

Ответ 4

Плохая практика использования оператора равенства == вместо ===.

undefined === undefined // true
null == undefined // true
null === undefined // false

object.x === undefined должен возвращать true, если x - неизвестное свойство.

В главе Плохие части JavaScript: хорошие части, Крокфорд пишет следующее:

Если вы попытаетесь извлечь значение из объект, и если объект не есть член с таким именем, он вместо этого возвращает значение undefined.

В дополнение к undefined, JavaScript имеет аналогичное значение, называемое нулем. Oни настолько похожи, что == думает, что они равны. Это смущает некоторых программистов думать, что они взаимозаменяемый, приводящий к коду типа

value = myObject[name];
if (value == null) {
    alert(name + ' not found.');
}

Это сравнение неправильного значения с неправильный оператор. Этот код работает потому что он содержит две ошибки, которые отмена один другой вне. Это сумасшедший способ программирования. Лучше написано например:

value = myObject[name];
if (value === undefined) {
    alert(name + ' not found.');
}

Ответ 5

От - JQuery_Core_Style_Guidelines

  • Глобальные переменные:
    typeof variable === "undefined"

  • Локальные переменные:
    variable === undefined

  • Свойства:
    object.prop === undefined

Ответ 6

var a;

typeof a === 'undefined'; // true
a === undefined; // true
typeof a === typeof undefined; // true
typeof a === typeof sdfuwehflj; // true

Ответ 7

А). Я никогда не имел и никогда не буду доверять никакому инструменту, который претендует на создание кода без пользовательского кодирования, который удваивается, где это графический инструмент.

В). У меня никогда не было никаких проблем с Facebook Connect. Это все еще простой старый код JavaScript, работающий в браузере, и undefined===undefined, где бы вы ни находились.

Короче говоря, вам нужно предоставить доказательства того, что ваш object.x действительно был undefined, а не null или иным образом, потому что я считаю, что невозможно, чтобы вы описывали это на самом деле - без обид:) - Я положил деньги на проблему, существующую в коде Терсуса.