JavaScriptの親オブジェクトを参照するときに、「変数が初期化されていない可能性があります」を避けるにはどうすればよいですか?

私はたくさんの "この警告を避けるにはどうすればいいですか"という質問があることを知っていますが、JavaScriptの最初のものは私のようです。この場合、自分自身の宣言の中で初期化しているものを参照したいと思っています:

var foo = new Foo({
  bar: new Bar({
    x: function(){
      doStuff(foo);
    }
  });
});

(これが馴染んでいれば、以前はExtJSを使用していたかもしれません - これはほとんどのものがビルドされている方法です)。

foo.bar.x()を呼び出すと、バー( bar )を所有するFoo( foo )それが関数( x )を呼び出しています。これはうまくいきますが、私のEclipseは "fooが初期化されていないかもしれない"と警告し、 doStuff(); の呼び出しを参照しています。 foo をまだ定義していません。もちろん、 foo が正常に構築されない限り、 x()を呼び出すことはできませんが、私のスタイルチェッカーは明らかにそれを理解していません。

だから私はこれに対処する方法を失っている。私は警告を無視すべきですか?それをそのようにマークする方法はありますか?私はもはや警告を受けませんか?私はこれを間違っているのですか?私は別の方法で私の参照を渡す必要がありますか?

5
日食を使用しないでください。より良いIDEがあります(WebStorm 3)
追加された 著者 Raynos,
良いキャッチ、申し訳ありません
追加された 著者 Coderer,
それはタイプミスですか? doStuff(f)の代わりに doStuff(foo)
追加された 著者 Duncan Smart,

4 答え

var Foo = function() { }

var Bar = function (obj) {
 //foo is not initialized
  obj.x();
 //called doStuff with undefined
}

var foo = new Foo({
  bar: new Bar({
    x: function(){
      doStuff(foo);
    }
  });
});

Eclipseは正しいです。また、WebStorm 3.0またはVisual Studio 11をJS IDEとして使用することを検討してください。

2
追加された
@Coderer オブジェクトを作成し、後で適切な名前のリンク方法でオブジェクト間のリンクを作成します。
追加された 著者 Raynos,
あなたのコードを@Codererで見ると、BarはFooに依存し、FooはBarに依存します。そのようなCirularの依存関係は常に悪です。
追加された 著者 Raynos,
@Codererそれはあなたの宣言で自分自身を参照していないと呼ばれる。そうすることは悪い習慣です(関数のような単純な宣言でない限り)
追加された 著者 Raynos,
@Coderer fooが定義されていないときにxが呼び出されるコンテキストを示したところです
追加された 著者 Raynos,
だから私は感情に同意しますが、これはUI用です。 "Foo"を "Dialog"と "Bar"を "Button"に置き換えます。ダイアログにはボタンがあり、ボタンをクリックすると、親ダイアログで "do stuff"する必要があります。そのためのより良いデザインはありますか?
追加された 著者 Coderer,
知っておいてください - 私がOPで説明している状況のように、「私に所有権を持っているオブジェクトへの参照を与える」という「正しい」方法はありますか?
追加された 著者 Coderer,
OK、JavaScriptをまだ十分にnewbしているので、クリックする前に約12回読む必要がありました。コンストラクタが構築中に x メソッドを呼び出すと、メソッドは foo を使用しようとします>は定義されていません。今は完全に意味をなさない。これが起こらないようにするパターンはありますか?私は1つ考えることができません。
追加された 著者 Coderer,
脇に:VSはオプションではありません(私は一般的にファンです...)。私はLinuxで開発しています。私はWebStormを真剣に見ていきます - ポインタのおかげで!
追加された 著者 Coderer,
なぜそれが不平を言うのか理解しています。私は foo 中に x()を呼び出すことができる実際の実行コンテキストがないことを99%確信しています>は未定義のままです。 Bar コンストラクタが完了する前に Bar コンストラクタは完了しますが、 Bar < Foo オブジェクトが完全に構築されるまで作成され( foo.bar に割り当てられた) foo 初期化されました。それが意味をなさなければ...
追加された 著者 Coderer,

これはjavascriptとは関係ありませんが、おそらくEclipseと関係しています。変数宣言はコードが実行される前に処理されるので、変数 foo はどこでも宣言できます。 doStuff が呼び出される前にいつでも初期化することができます(宣言していない変数を初期化することは悪いとみなされます)。

1
追加された

まず、Fooが構築されます。そのコンストラクターに、新しいBarが渡され、変数fooを使用する関数が渡されます。

しかし、fooは、Fooのコンストラクタが終了した後にのみ値が割り当てられます。その時点で、宣言されていない変数fooを使用して関数がすでに宣言されています。 関数がBarまたはFooのコンストラクターで使用されている場合、関数は失敗します。

0
追加された
まず、ローカル変数オブジェクトのプロパティとして foo が作成されます。コードはグローバルスコープ内にあるようですので、コードが実行される前にグローバルオブジェクト(グローバル変数)のプロパティです。 doStuff が呼び出されると、 foo が存在しますが、値が割り当てられていない可能性があります(未定義の可能性があります)。
追加された 著者 RobG,
私はそれを示唆していない、私はどのように変数が割り当てられていない可能性がある説明しているdoStuffが呼び出されます。私はそれがそうであると言っているわけではありませんが、警告が出されます。このような状況で foo がプロパティとして宣言されているのか、グローバルとして宣言されているのかはまったく関係ありません。警告を防ぐ最も簡単な方法は、この割り当てを呼び出す前に foo に値(nullでもかまいません)を割り当てることです。
追加された 著者 GolezTrol,
あなたはOPのコードがエラーを投げることを示唆していますか?それはないから。
追加された 著者 nrabinowitz,

私は@ RobGが正しいと思います。これはEclipseの問題であり、おそらくそれを処理するのが最善でしょう。しかし、それを避けたい場合は、初期化する前に foo を宣言することができます。これはEclipseが不平を言うのを防ぐでしょう:

var foo;
foo = new Foo({
  bar: new Bar({
    x: function(){
      doStuff(foo);
    }
  });
});
0
追加された
私はJSLintを試してみたいと思っていますが、警告をすべて修正するのには時間がかかりますので、Eclipseの「寛大な」警告を最初に試してみたかったのです。値は初期化されるべきではないことが分かっていますが、何が間違っているかを考える上で価値があります(初期化コードが条件付きの場合など)
追加された 著者 Coderer,
宣言しただけではまだ宣言されていませんが、技術的には "初期化されていません"と宣言するだけで、 var foo = "some garbage"のようなことをするのは苦労します。 foo = new Foo(....);
追加された 著者 Coderer,
Javascriptでは変数に値を割り当てる必要はありません(初期化されている)。 jslintでコードを実行し、何を得るのか見てみましょう!
追加された 著者 RobG,
うん、あなたは null に初期化することができますが、その時点であなたのIDEに合うようにコーディングスタイルを調整するのは良いことではありません。
追加された 著者 nrabinowitz,
JavaScript - 日本のコミュニティ
JavaScript - 日本のコミュニティ
2 参加者の

日本人コミュニティのjavascript