2012-01-27 5 views
0

У меня есть хорошее понимание разницы между неопределенным и нулевым и тот факт, что JavaScript отбрасывает практически что-либо в логическом, в частности, от null до false.JavaScript странное поведение null

Мой вопрос: почему второе предупреждение срабатывает как в FF 9, так и в IE 9? (Это небольшой тестовый сценарий, основанный на гораздо более сложном сценарии. Он предназначен только для иллюстрации проблемы ...)

Я ожидаю. оператор имеет приоритет, а выражение возвращает null, которое затем будет передано логическому значению false. Добавление скобок,! (Context.isNull), не имеет значения.

<!DOCTYPE html> 
<html lang="en"> 
    <head> 
    <title>Test</title> 
    </head> 

    <body> 
    <script type="text/javascript"> 
     var context = this; 
     var isNull = null; 

     var aFunc = function() { 
      alert(context.isNull); 
      if (!context.isNull) { 
       alert("Is !context.isNull really true?"); 
      } 
     }; 

     aFunc(); 

    </script> 
    </body> 
</html> 
+0

Где '.isNull' приходят от любого способа? – 0x499602D2

+0

@David 'var isNull = null;' –

+0

@David: В глобальной области действия переменные 'var''d назначаются как свойства для« глобального объекта »(в этом случае« окно »); поэтому 'var context = this' эквивалентен' window.context = window', а 'var isNull = null' -' window.isNull = null'. – ruakh

ответ

0

Первому, «Thank вы!" всем, кто ответил.

Я глубоко смущен. Это была поздняя пятница в длинный день, и я перевернул логику в моей голове. Он делает именно то, что должен. Проблема заключалась в том, что фактический код проверял что-то существующее, и я написал свой тестовый пример назад.

Что происходит, так это то, что значение null передается в значение false, а false - true, поэтому выполняется код «if». Мой (мозговой мертв) выбор названий полей скрывает проблему.

Причина

var context = this; 

является то, что реальный код находится внутри конструктора. Поле «контекст» затем «закрывается», когда создается функция, которая сохраняет ссылку на объект, который строится. Это важно, когда функция привязана к другому объекту (обычно как обработчик события), так что тело функции может обращаться к содержимому исходного объекта. Конечно, в этом примере «это» относится к глобальному объекту, который не имеет большого значения.

1

context.isNull является this.isNull является window.isNull, который является null, что логическое значение FALSE. Затем вы добавляете !, который инвертирует это, в результате чего получается общее выражение true, поэтому вычисляется тело if.

+0

context.isNull = undefined, который является логическим false –

+0

@SKS Нет, context.isNull === null. –

+0

Чтобы разработать, @SKS: 'context === this === window' для кода OP, а' window.isNull' определяется как 'null' по строке' var isNull = null; '. – Amber

0

Редактировать: Я пропустил контекст = эта часть. Как и другие упомянутые, context = this => context = window.

Кроме того, var isNull = null; в глобальном масштабе подразумевает => window.isNull = null.

Что будет, как,

if (!context.isNull) => if (!window.isNull) => 
          if (!null) => if (!false) => if(true) 

если (! Context.isNull) => если (! Не определено) => если (! Ложно) => если (истина)

+0

Да, ты прав. Так что я удалил свой пост и проголосовал за вас, вы все равно выражаете экспансии. –

+2

'isNull' определен в окне; 'this.isNull' будет оценивать значение' null'. Конечный результат тот же, хотя. –

+0

@DaveNewton Мой плохой, я раньше пропустил часть 'context = this' .. Thx для исправления. –

0

Поскольку this.isNull будет оцениваться в null. !null правдивый.

0

Я полагаю, что вы ожидаете, что !null будет null? Это имеет смысл —, что тип three-valued logic используется в SQL —, но это не так, как он работает в JavaScript. В JavaScript ! заставляет свой аргумент интерпретироваться как логическое значение, и, как вы знаете, null, интерпретируется как логическое значение, становится false.

0

При размещении в булевом контексте значение null будет оцениваться до false. Оператор unary negation! отличает null с булевым значением - false - затем сбрасывает с булевым значением в обратном направлении: true. Итак, ! делает две вещи - она ​​бросает и переворачивает.

0

isNull - это локальная переменная. Он не является свойством объекта, представленного в настоящее время «этим», если вы добавляете this.isNull = null или context.isNull = null, вы получите то, что ищете.

Я думаю, что он получает истинный результат, потому что context.isNull не определена, а с неопределенными подсчетов как ложный результат инвертированием

Считает, что это также дает предупреждение:

var aFunc = function() { 
     alert(context.isNull); 
     if (!context.foo) { 
      alert("Is !context.isNull really true?"); 
     } 
    }; 
+0

Переменная определяется в контексте окна. Попробуйте это из консоли: 'var foo_bar_baz = 42; var context = this; console.log (context.foo_bar_baz); ' –

+0

А вы правы ... Я думал, что он определил его в функции, возможно, потому, что я избегаю использования глобальных переменных, таких как чума :) – Gus