2012-01-27 115 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