[解決済み] var キーワードを使用しない変数宣言
質問
w3schoolsに書いてあります。
var"を使わずに変数を宣言した場合、その変数は常にGLOBALになります。
関数内でグローバル変数を宣言することは有用でしょうか?イベントハンドラでいくつかのグローバル変数を宣言することは想像できますが、それは何のためにあるのでしょうか?RAMのより良い使用法?
どのように解決するのですか?
いいえ、RAM の利点などありません。
w3schoolsが話しているのは、私が呼んでいるものです。 暗黙のグローバルの恐ろしさ . この関数を考えてみましょう。
function foo() {
var variable1, variable2;
variable1 = 5;
varaible2 = 6;
return variable1 + variable2;
}
単純に見えますが、これは
NaN
ではなく
11
のタイプミスのため
varaible2 = 6;
の行にタイプミスがあるためです。そして、タイプミスされた名前のグローバル変数が作成されます。
function foo() {
var variable1, variable2;
variable1 = 5;
varaible2 = 6;
return variable1 + variable2;
}
console.log(foo()); // NaN
console.log(varaible2); // 6?!?!?!
これは、この関数が代入する
varaible2
(タイプミスに注意してください)、しかし
varaible2
はどこにも宣言されていません。JavaScript のスコープチェーンの仕組みにより、これは結局のところ
グローバルオブジェクト
(これは
window
としてアクセスできます)。
これはルーズモードJavaScriptの特徴で、完全に宣言されていない識別子への代入はエラーではありません。代わりに、グローバルオブジェクトのプロパティを作成し、グローバルオブジェクトのプロパティはグローバル変数になります。(ES5までは、すべてのグローバルはグローバルオブジェクトのプロパティでした。しかし、ES2015では、グローバルオブジェクトのプロパティではない新しい種類のグローバルが追加されました。グローバルスコープ
let
,
const
そして
class
は新しい種類のグローバルを作成します)。
私の例はタイプミスですが、もちろん、やろうと思えばわざとそうすることも可能です。結局のところ、これは言語の明確に定義された部分なのです。というわけで。
myNewGlobal = 42;
...どこであれ
myNewGlobal
が宣言されていないところでは、新しいグローバルが作成されます。
しかし、私は決して意図的にそれをしないことを強くお勧めします。それはコードを読みにくくし、保守しにくくし、そしてそのコードはJavaScriptモジュールがより一般的になり普及したときに互換性がなくなります。実行時に関数内からグローバル変数を作成する必要が本当にあるなら (すでに赤旗ですが、正当な理由があります)、明示的に
window
のプロパティに代入してください (あるいは、あなたの環境でグローバルオブジェクトを参照しているものなら何でも構いません。これは
window
です)。
window.myNewGlobal = 42;
実際、私はES5の
ストリクトモード
. ストリクトモードでは、宣言されていない識別子への代入は、黙ってグローバルを作成するのではなく、エラーになります。もしストリクトモードを使っていたら
foo
の問題を診断するのはもっと簡単だったでしょう。
"use strict"; // Turns on strict mode for this compilation unit
function foo() {
var variable1, variable2;
variable1 = 5;
varaible2 = 6; // <=== ReferenceError
return variable1 + variable2;
}
console.log(foo());
少し余談ですが、一般的に、可能な限りグローバルは避けることをお勧めします。グローバル名前空間は、すでにブラウザー上で非常に散らかっています。ブラウザは DOM 内のすべての要素に対して、グローバルに
id
を持つほとんどの要素、そして
name
を持つほとんどの要素に対応し、いくつかの定義済みグローバル (例えば
title
のような) いくつかの定義済みのグローバルがあり、これらはあなたのコードと簡単に衝突する可能性があります。
その代わりに、自分自身で素敵なスコープ関数を定義し、その中にシンボルを入れてください。
(function() {
var your, symbols, here, if_they_need, to_be_shared, amongst_functions;
function doSomething() {
}
function doSomethingElse() {
}
})();
そして、その場合、ストリクトモードを有効にするとよいでしょう。
(function() {
"use strict";
var your, symbols, here, if_they_need, to_be_shared, amongst_functions;
function doSomething() {
}
function doSomethingElse() {
}
})();
...これは、前述のように、未宣言の識別子への代入をエラーにする利点があります (さらに 他の様々な役に立つもの ).
なお、JavaScriptの
モジュール
(ES2015 で追加されましたが、今になってようやくその道が開かれつつあります) では、デフォルトでストリクトモードが有効になっています。(これは
class
の定義でも同様です(これも ES2015 の新機能です)。
関連
-
[解決済み] AngularJSのグローバル変数
-
[解決済み] let "と "var "の使い分けは?
-
[解決済み] 関数内でグローバル変数を使用する
-
[解決済み] JavaScriptでNULL、未定義、空白の変数をチェックする標準的な関数はありますか?
-
[解決済み] jQueryを使用しない$(document).ready相当
-
[解決済み] JavaScriptの変数のスコープとは何ですか?
-
[解決済み] JavaScriptの「new」キーワードとは何ですか?
-
[解決済み] varキーワードの目的と、どのような場合に使用する(または省略する)べきですか?
-
[解決済み] JavaScriptの配列宣言で「Array()」と「[]」はどう違うのですか?
-
[解決済み] 兄弟ノードを選択する方法はありますか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] 文字列がすべて同じ部分文字列で構成されているかどうかを調べるにはどうすればよいですか?
-
[解決済み] JavaScriptでの大文字小文字を区別しない正規表現
-
[解決済み] イテレータでmap()を使用する
-
[解決済み] Node.jsのES6クラスをrequireで作る
-
[解決済み] JavaScriptのArray.sort()メソッドでシャッフルするのは正しいのか?
-
[解決済み] jQueryのバージョン1、バージョン2、バージョン3の違いは何ですか?[クローズド]
-
[解決済み] JavaScriptの文字列プリミティブとStringオブジェクトの違いは何ですか?
-
[解決済み] これは純関数ですか?
-
[解決済み] リダイレクトされずにHTMLフォームを送信する方法
-
[解決済み] JavaScriptでDIVを表示・非表示にするには?