12

私はjsフレームワーク「Sencha」についてDavidMarkから次の分析を読んでいました:https ://gist.github.com/3279190そしてそこで彼は述べています...

彼らが望んでいたのはグローバル変数でしたが、最終的にはグローバルオブジェクトのプロパティになりました。仕様と(および実装履歴)によると、2つの間に十分な違いがあり、それらを混同しないように注意する必要があります(ここで行われているように)。

...しかし、私が知っている限り、var my_global = 123;と(ブラウザ環境では)の間に違いはありませんでしたwindow.my_global = 123;(この例では、環境はブラウザであると想定していました-したがって、を使用しましたが、明らかに代わりにwindow使用することもできましたthis.my_global異なる環境で実行すると、グローバルオブジェクトは異なります)。

しかし、その小さな不一致を無視すると、グローバルオブジェクトへのプロパティの割り当てとグローバル変数の作成に違いがありますか?私はそうは思いませんでした。グローバル変数を作成することは、プロパティをグローバルオブジェクトに割り当てるもう1つの方法でした。

一部のブラウザで「my_global」のIDを持つ要素がある場合、問題が発生する可能性があると思います。これにより、JavaScriptが正しいものを参照する際に問題が発生する可能性がありますが、その問題の原因/原因がわかりません(たとえば、プロパティをグローバルオブジェクトに割り当てると、要素IDの問題が発生しますか、それとも要素IDの問題を引き起こすグローバル変数を宣言しますか?)

誰かが私のためにこれを明確にすることができますか?

4

3 に答える 3

12

更新、2020年4月

D. Pardalのコメントに記載されているように、2012年に書かれた以下の最初の文は、ESモジュール仕様)をサポートする環境では常に当てはまるとは限りません。ESモジュール内では、varステートメントはグローバルオブジェクトのプロパティを生成しません。

元の回答

グローバルスコープでを使用して作成された変数varは、グローバルオブジェクトのプロパティを作成します。ただし、このプロパティは、を使用して作成されていないグローバルオブジェクトのプロパティとは動作が異なりますvar

まず、変数宣言の実行方法に違いがあります。varグローバルスコープのステートメントは、コードが実行される前にグローバルオブジェクトのプロパティを作成します。これは、一般にホイストと呼ばれる効果であり、Web全体で十分に文書化されています(以下の参照を参照)。 。

次に、で作成されていないグローバルオブジェクトのプロパティとは異なり、グローバル変数は演算子varを使用して削除できません(ただし、これは古いバージョンのIEでは当てはまりません)。変数の削除には使用できません。この違いは、すべてのオブジェクトプロパティが持つ内部プロパティ属性にあります。これらの属性は、ECMAScript仕様で指定されています。ECMAScript 5の用語では、属性を使用してグローバルオブジェクトのプロパティを作成しますが、(グローバルスコープでは)属性を使用してプロパティを作成します。deletedeletevar foo = "bar"foo[[Configurable]]falsethis.foo = "bar"foo[[Configurable]]true

参照:

  • Dmitry Soshnikovは、これについて彼の優れた一連の記事、ECMAScript262-3で詳細に書いています。第2章をすべて読むことをお勧めしますが、最も関連性の高いセクションは「 変数について」と呼ばれています。

  • 以前にリンクされたkangaxの記事には、ブラウザのバグと逸脱の多くの関連情報と詳細に加えて、に関するさらなる癖が含まれていますwindow

  • この回答と同じリソースの多くにリンクしているJavaScriptの記事のAngusCrollの変数とプロパティ。

  • 仕様:ECMAScript5.1

于 2012-09-17T09:48:52.193 に答える
0

私は実際的な違いを認識していませんが、グローバルとして参照することとwindow.varとして参照することの間には確かにいくつかの違いがあります。簡単な例:

'use_strict';
console.info(window.foo);
console.info(foo);

window.fooは単にundefinedを返します。fooはundefinedをエラーとして返します。そうです、それらは異なります。しかし、良いコード(私の例は非常に悪いコードです)では、違いはないように見えます。(しかし、もしあれば、私はそれについてもっと知りたいです:))

于 2012-09-15T19:42:09.450 に答える
-2
var count = 123

var global_object = {
    count:var = 456
console.log(this.count) //returns 456

}

console.log(count) //returns 123

console.log(global_object) //returns 456

上記では、カウントは最初にグローバル変数として定義されています。次に、グローバルオブジェクト内のプロパティとして定義されます。グローバルオブジェクト内の定義は、そのオブジェクトに対してローカルです。

私が最初にこれを投稿したとき、私には起こらなかった私の答えに問題があります。上記の最も賛成の回答では、質問のグローバル変数の場合はその定義に「var」が使用されていますが、グローバルオブジェクトの場合は「var」が使用されていないことが正しく示されています。私はまだスコープがここで機能することを期待しています(ActionScriptで機能します)。

上記の例には、他にもいくつか問題があります。count:var=は私には間違っています。多分それはvarcount=456であるはずです。しかし; それでも、関数内で宣言された変数は、その関数内でのみスコープを持つことを期待します。したがって、この例のconsole.log式は当てはまるはずです。

于 2012-09-15T17:19:22.133 に答える