2011-12-22 16 views
2

さて、このコードを見つけました。固有のJavaScript構造体:オブジェクト定義内のオブジェクト型の変数

どうしてこれはどういう仕組みですか?変数を解決するためにJavaScriptが使用する悪意のあるスキームの種類

私が見ているのは、C++の人です。クラス/オブジェクト定義には、定義されているクラスのオブジェクトへの存在しない参照が含まれています。真剣に、どう?

(正直に言うと、私は部分的に理解して - 私は... JSの名前をどのように解決するか、いつのstrawmanコンセプトを導き出すことができますが、多分この方法では問題は他の誰か、いつかにより使用されるであろう)

ギルティコード:

function Sio() { 
    this.someValue = 5; 
    this.doStuff = function() { 
     console.log("look: "+howDoYouResolveThisYouFoulCreature.someValue); 
    }; 
} 

var howDoYouResolveThisYouFoulCreature = new Sio(); 

これは間違っています。

答えて

3

たくさん、と私はあなたにトラブルを与えているかわからないんだけど...

二つの最も可能性の高いものはnew/thisvarです。

あなたがthisの値は、あなたがそれを呼び出すしたコンテキストによって決定された関数を呼び出す

new/this

キーワードnewを使用する場合、関数のインスタンスを作成し、そのインスタンスをコンテキストにします。

howDoYouResolveThisYouFoulCreature.doStuff()に電話すると、そのインスタンスをグローバルとしてアクセスしています。foo.doStuff()は(Sioの異なるインスタンス間で機能を再利用可能になります)doStuff()のinvokation

var

    ため fooコンテキストを作るので

    this.doStuff = function() { 
        console.log("look: "+ this.someValue); 
    }; 
    

    :これは通常に、より理にかなって

  1. JavaScriptのスコープは、機能レベルにあります。
  2. 変数
  3. その機能には、doStuff機能、また混乱

を避けるために、関数の先頭に単一varステートメントを使用することをお勧めと考えられていることを、機能意志の範囲内の任意の場所var somethingを使用してhowDoYouResolveThisYouFoulCreatureに値が入る前に呼び出されません。その点までは、関数が構文的に正しいということだけが重要です。変数がどの型かは関係ありません。

1

howDoYouResolveThisYouFoulCreatureを作成する前にfunction()this.doStuffが実行されていないために機能します。 doStuff()が呼び出された変数名にかかわらず、これが常にconsole.logになるように、多くの新しいSio()のことを念頭に置いておいてください。だから、機能doStuffが割り当てられている時に、varは既に宣言されている

var howDoYouResolveThisYouFoulCreature; 
howDoYouResolveThisYouFoulCreature = new Sio(); 

var howDoYouResolveThisYouFoulCreature = new Sio(); 

が...実際に解決されますので、

1

は、これが動作します。

編集:私は愚かであったことを忘れてしまった。それはpimvdbが正しいと判明し、ここで証明(also on jsfiddle)です:

function A() { 
    this.logValue = function() { 
     if (b === undefined) { 
      console.log('Wah, wah, wah...'); 
     } else { 
      console.log(b.someValue); 
     } 
    }; 
} 

function B() { 
    this.someValue = 42; 
} 

var a = new A(); 
a.logValue(); // Wah, wah, wah... 

var b = new B(); 
a.logValue(); // 42 

だから、実行コンテキストがキーです。 Sio(または、この場合はA)が構築されるとき、範囲はbかもしれません。は、ある時点で定義されます。変数は、関数が呼び出されるまで解決されません。その時点で関数が定義されます。か否か。いいえ。 :-)ここでの概念の

+0

これは必ずしも問題ではありません。その関数が存在しない変数を参照している場合は、変数に関数を割り当てることもできます。 – pimvdb

関連する問題