2012-01-27 101 views
0

我很好地理解了undefined和null之间的区别,以及JavaScript将布尔转换为任何东西的事实,特别是null转为false。JavaScript奇怪的空行为

我的问题是这样的:为什么在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 2012-01-27 23:22:42

+0

@David'var isNull = null;' – 2012-01-27 23:24:10

+0

@David:在全局作用域中,var变量被赋值为“全局对象”(本例中为'window')的属性。所以'var context = this'相当于'window.context = window','var isNull = null'相当于'window.isNull = null'。 – ruakh 2012-01-27 23:26:29

回答

0

首先,“谢谢您!”给所有回复的人。

我深感尴尬。星期五是漫长的一天晚上,我倒在了脑海里的逻辑。它正在做它应该做的。问题在于实际的代码正在检查现有的东西,并且我向后写了测试用例。

会发生什么是null将转换为false,false为true,因此将执行“if”代码。我的(脑死亡)字段名称选择掩盖了问题。

原因

var context = this; 

是真正的代码坐在一个构造函数中。然后,在创建函数时,“上下文”字段将“关闭”,这会保留对正在构建的对象的引用。当函数连接到另一个对象(通常作为事件处理程序)时,这很重要,以便函数体可以访问原始对象的内容。当然,在这个例子中,“this”是指全局对象,它没有太多的用处。

1

context.isNullthis.isNullwindow.isNullnull,这是布尔假。然后,您添加!,将其反转,从而产生总体true表达式,因此您的if正文将被评估。

+0

context.isNull = undefined布尔值false – 2012-01-27 23:20:05

+0

@SKS否,context.isNull === null。 – 2012-01-27 23:23:39

+0

要详细说明,OP代码的@SKS:'context ===这个===窗口','var isNull = null;'行定义了'window.isNull'。 – Amber 2012-01-27 23:31:22

0

编辑:我错过了上下文= this部分..正如其他提到的,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

是的,你说得对。因此,我删除了我的帖子,并投了票,反正你更清楚地表达了扩展。 – 2012-01-27 23:19:41

+2

'isNull'在窗口中定义; 'this.isNull'将评估为'null'。但最终结果是一样的。 – 2012-01-27 23:21:47

+0

@DaveNewton我的不好,我错过了早期的'context = this'部分。 – 2012-01-28 17:11:07

0

因为this.isNull将评估为null!null是truthy。

0

我想你所期待的!nullnull?这是有道理的—那种three-valued logic用于SQL —,但这不是它在JavaScript中的工作原理。在JavaScript中,!强制其参数被解释为布尔值,并且如您所知,null在解释为布尔值时变为false

0

当放置在布尔上下文中时,null值将评估为falseunary negation运营商!null转换为布尔值 - false - 然后翻转布尔值为其相反值:true。所以!做了两件事 - 它投掷和翻转。

0

isNull是局部变量。如果添加this.isNull = null或context.isNull = null,则它不是目前由“this”表示的对象的属性,您将获得所需的内容。

我认为他得到真正的结果,因为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);' – 2012-01-27 23:31:53

+0

啊,你是对的......我想他已经在函数中定义了它,可能是因为我避免使用像鼠疫这样的全局变量:) – Gus 2012-01-27 23:43:12