2012-01-27 9 views
0

私は、未定義とnullとの違いや、JavaScriptが何かをブール値、特にnullからfalseにキャストしているということをよく理解しています。JavaScript strange nullの動作

私の質問は次のとおりです。FF 9とIE 9の両方で2番目のアラートがトリガーされるのはなぜですか? (これははるかに複雑なスクリプトに基づいている小さなテストスクリプトです。問題を説明するためのものです...)

私は期待しています。演算子が優先され、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''変数は"グローバルオブジェクト "(この場合は' window')にプロパティとして割り当てられます。したがって、 'var context = this'は' window.context = window'に相当し、 'var isNull = null'は' window.isNull = null'になります。 – ruakh

答えて

0

まず、「感謝を君は!"返答したすべての人に

私は深く恥ずかしいです。長い一日の金曜日の遅れで、私は私の頭の中で論理を反転させました。それは正確に何をすべきかをしています。問題は、実際のコードで何かが存在するかどうかをチェックしていたことです。テストケースを後ろに書きました。

何が起こるかは、nullがfalseにキャストされ、!falseがtrueであるため、 "if"コードが実行されます。フィールド名の私の(脳死し)選択は、問題をあいまいにします。

var context = this; 

理由は、実際のコードは、コンストラクタ内で座っているということです。関数が作成されると、フィールド「コンテキスト」は「クローズ」され、構築されているオブジェクトへの参照が保持されます。これは、関数本体が別のオブジェクト(通常はイベントハンドラとして)にアタッチされている場合に重要なので、関数本体は元のオブジェクトの内容にアクセスできます。もちろん、この例では、 "this"は多目的に機能しないグローバルオブジェクトを指します。

1

context.isNullthis.isNullあるブール偽である、nullあるwindow.isNullです。次に、!を追加すると、その結果が反転し、全体としてtrueの式が返され、ifの本文が評価されます。

+0

context.isNull =ブール値falseの未定義 –

+0

@SKSいいえ、context.isNull === null。 –

+0

詳しくは、OPコードの@SKS: 'context === this === window'を参照してください。' window.isNull'は、 'var isNull = null;'行によって 'null'として定義されています。 – Amber

0

編集:私は文脈=この部分を見逃していました。他にも言及したように、context = this => context = window。

また、var isNull = null;グローバルスコープでは、=> window.isNull = nullを意味します。 (!context.isNull)=>(もし!未定義)=>ので(真)

+0

ええ、そうです。だから私は自分の投稿を削除し、あなたの投票で投票したが、とにかく展開をもっとはっきりと表現する。 –

+2

'isNull'はウィンドウ上で定義されています。 'this.isNull'は' null'と評価されます。しかし、最終結果は同じです。 –

+0

@DaveNewton私の悪い、私は以前の 'context = this'の部分を見逃しました..訂正のためのThx。 –

0

場合(!偽)=>もしあれば

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

、のようになります。

this.isNullnullと評価されます。 !nullは真実です。

0

!nullnullとなると思いますか?その意味は— three-valued logicのSQLで使用されていますが、それはJavaScriptでの動作とは異なります。 JavaScriptでは、!はその引数をブール値として解釈します。ご存知のように、nullはブール値として解釈されるとfalseになります。

0

ブール値のコンテキストに配置すると、nullの値はfalseと評価されます。 unary negation演算子!は、nullをブール値-false-にキャストし、次にのブール値を反対の値trueに反転します。だから!は2つのことを行います - それは投げられ、反転します。

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;コンソールのログ(context.foo_bar_baz); ' –

+0

ああ、そうだ...私は彼が関数でそれを定義したと思っていた、おそらく私はペストのようなグローバルを使用しないでください:) – Gus