JavaScript: не определено! == не определено? - PullRequest
65 голосов
/ 22 апреля 2009

ПРИМЕЧАНИЕ. Согласно 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 при попытке вызвать функции API Facebook.

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

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.

Ответы [ 7 ]

89 голосов
/ 22 апреля 2009

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

typeof x == "undefined"

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

61 голосов
/ 26 апреля 2009

Оказывается, вы можете установить для window.undefined все, что захотите, и поэтому получите object.x !== undefined, когда object.x - это real 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
19 голосов
/ 02 июля 2011

Я хотел бы опубликовать важную информацию о 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, вы получите ИСКЛЮЧЕНИЕ ОШИБКИ и неожиданно вообще не увидите оповещений.

Вместо 'Выполнение важной работы ниже' ваш сценарий будет ПРЕКРАТИТЬ НЕОБХОДИМЫЙ, создавая необработанное исключение в самой первой строке.


Вот единственный пуленепробиваемый способ проверки 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! */  

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

15 голосов
/ 23 апреля 2009

Неправильно использовать оператор равенства == вместо ===.

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

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

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

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

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

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

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

value = myObject[name];
if (value === undefined) {
    alert(name + ' not found.');
}
10 голосов
/ 09 декабря 2011

С - JQuery_Core_Style_Guidelines

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

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

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

4 голосов
/ 17 ноября 2011
var a;

typeof a === 'undefined'; // true
a === undefined; // true
typeof a === typeof undefined; // true
typeof a === typeof sdfuwehflj; // true
2 голосов
/ 23 апреля 2009

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...