変数の宣言に違いはありますか?
var a=0; //1
...こちらです:
a=0; //2
...または:
window.a=0; //3
グローバルスコープで?
変数の宣言に違いはありますか?
var a=0; //1
...こちらです:
a=0; //2
...または:
window.a=0; //3
グローバルスコープで?
回答:
はい、実際には大きな違いはありませんが、いくつかの違いがあります。
4番目の方法があり、ES2015(ES6)の時点でさらに2つあります。最後に4番目の方法を追加しましたが、ES2015の方法を#1の後に挿入したので(理由がわかります)、次のようになります。
var a = 0; // 1
let a = 0; // 1.1 (new with ES2015)
const a = 0; // 1.2 (new with ES2015)
a = 0; // 2
window.a = 0; // 3
this.a = 0; // 4
#1 var a = 0;
これにより、グローバルオブジェクトのプロパティでもあるグローバル変数が作成されます。これはwindow、ブラウザー上(またはthis厳密でないコードではグローバルスコープを介して)にアクセスします。他の一部のプロパティとは異なり、プロパティはを介して削除できませんdelete。
仕様では、グローバル環境のオブジェクト環境レコードに識別子バインディングを作成します。グローバルオブジェクトはグローバル環境のオブジェクトである環境レコードの識別子バインディングが保持されるため、グローバルオブジェクトのプロパティになります。これがプロパティが削除不可である理由です。これは単なるプロパティではなく、識別子バインディングです。
バインディング(変数)は、コードの最初の行が実行される前に定義されます(以下の「いつvar起こるか」を参照)。
IE8以前では、で作成されたプロパティwindowは列挙可能ではないことに注意してください(for..inステートメントには表示されません)。IE9、Chrome、Firefox、Operaでは列挙可能です。
#1.1 let a = 0;
これにより、グローバルオブジェクトのプロパティではないグローバル変数が作成されます。これはES2015の新しいことです。
仕様上、オブジェクトの環境レコードではなく、グローバル環境の宣言型環境レコードに識別子バインディングを作成します。地球環境は、スプリット環境録音、グローバルオブジェクト(上行くすべての古いもののために有するもので一意であるオブジェクトのすべての新しいもの(のための環境レコード)と別のlet、const、およびによって作成された機能をclass、そうでありません)グローバルオブジェクトに行きます。
バインディングは、それを囲むブロック内のステップバイステップコードが実行される前に(この場合は、グローバルコードが実行される前に)作成されますが、ステップバイステップ実行がステートメントに到達するまでは、アクセスできませんlet。実行がletステートメントに到達すると、変数にアクセスできます。(以下の「いつlet、constどうなるか」を参照してください。)
#1.2 const a = 0;
グローバルオブジェクトのプロパティではないグローバル定数を作成します。
constletイニシャライザ(= valueパーツ)を提供する必要があることと、作成された定数の値を変更できないことを除いて、まったく同じです。裏では、それはまったく同じですletが、値を変更できないことを示すフラグが識別子バインディングにあります。を使用constすると、次の3つのことが行われます。
#2 a = 0;
これにより、グローバルオブジェクトにプロパティが暗黙的に作成されます。これは通常のプロパティなので、削除できます。私はこれを行わないことをお勧めします。後でコードを読む人にとっては不明確になる可能性があります。ES5のストリクトモードを使用している場合、これを行う(存在しない変数に割り当てる)とエラーになります。strictモードを使用するのは、いくつかの理由の1つです。
そして興味深いことに、再びIE8以前では、プロパティは列挙可能ではありません(for..inステートメントには表示されません)。これは奇妙で、特に以下の#3に示されています。
#3 window.a = 0;
これにより、グローバルオブジェクトwindowを参照するグローバルを使用して、グローバルオブジェクトにプロパティが明示的に作成されます(ブラウザー上。一部の非ブラウザー環境には、globalNodeJS などの同等のグローバル変数があります)。これは通常のプロパティなので、削除できます。
このプロパティは、IE8以前、および私が試した他のすべてのブラウザーで列挙可能です。
#4 this.a = 0;
#3とまったく同じですthisが、グローバルではなくグローバルオブジェクトを参照しますwindow。ただし、これは厳密モードでthisは機能しません。厳密モードのグローバルコードでは、グローバルオブジェクトへの参照がないためです(undefined代わりに値があります)。
「削除」または「削除」とはどういう意味aですか?正確に:deleteキーワードを使用してプロパティを(完全に)削除する
window.a = 0;
display("'a' in window? " + ('a' in window)); // displays "true"
delete window.a;
display("'a' in window? " + ('a' in window)); // displays "false"
deleteオブジェクトからプロパティを完全に削除します。あなたは、プロパティが追加でそれを行うことはできませんwindowを介して間接的にvar、deleteのいずれか黙って無視されるか(JavaScriptの実装に、あなたがstrictモードにいるかによって)例外をスローしています。
警告:再びIE8(おそらく以前、および壊れた「互換性」モードのIE9-IE11):window許可されているはずの場合でも、オブジェクトのプロパティを削除できません。さらに悪いことに、試行すると例外がスローされます(IE8や他のブラウザーでこの実験を試してください)。したがって、windowオブジェクトから削除するときは、防御的でなければなりません。
try {
delete window.prop;
}
catch (e) {
window.prop = undefined;
}
これはプロパティを削除しようとし、例外がスローされた場合は次善の策を実行してプロパティをに設定しますundefined。
これはオブジェクトにのみ適用され、window(私が知る限り)IE8以前(または壊れた「互換性」モードのIE9-IE11)にのみ適用されます。window上記のルールに従って、他のブラウザでもプロパティを削除できます。
var起こるか経由で定義された変数var文が前に作成された任意の実行コンテキストでのステップバイステップのコードが実行され、財産はよく存在するので、前varの文。
これは紛らわしいので、見てみましょう。
display("foo in window? " + ('foo' in window)); // displays "true"
display("window.foo = " + window.foo); // displays "undefined"
display("bar in window? " + ('bar' in window)); // displays "false"
display("window.bar = " + window.bar); // displays "undefined"
var foo = "f";
bar = "b";
display("foo in window? " + ('foo' in window)); // displays "true"
display("window.foo = " + window.foo); // displays "f"
display("bar in window? " + ('bar' in window)); // displays "true"
display("window.bar = " + window.bar); // displays "b"
ライブの例:
ご覧のとおり、シンボルfooは最初の行の前に定義されていますが、シンボルは定義されてbarいません。var foo = "f";ステートメントがある場合、実際には2つのことが行われます。シンボルの定義。コードの最初の行が実行される前に行われます。そして、そのシンボルへの割り当てを行います。これは、ラインがステップバイステップのフローにある場合に発生します。これはvar、var fooパーツがスコープの最上部に移動(「巻き上げ」)されますが、foo = "f"パーツは元の場所に残るため、「巻き上げ」と呼ばれます。(貧血の小さなブログで誤解さvarれている貧しい人々を参照してください。)
letとconst起こりますletそして、constは異なっているvarいくつかの方法インチ 問題に関連する方法は、それらが定義するバインディングは、ステップバイステップのコードが実行される前に作成されますが、or ステートメントに到達するまでアクセスできないということです。letconst
これが実行されている間:
display(a); // undefined
var a = 0;
display(a); // 0
これはエラーをスローします:
display(a); // ReferenceError: a is not defined
let a = 0;
display(a);
質問と実際には関係のない、letとのその他の2つのconst違いvarは次のとおりです。
var常に(グローバルコードを通して、またはそれが現れる関数内の機能コード全体)全体の実行コンテキストに適用されますが、letおよびconst内のみ適用されますブロック、彼らが表示されます。つまり、var機能(またはグローバル)スコープletをconst持っていますが、ブロックスコープを持っています。
var a同じコンテキストで繰り返しても問題はありませんが、let a(またはconst a)がある場合、別のlet aまたはa const aまたはa var aがあると構文エラーになります。
次の例は、そのことletを示しておりconst、そのブロック内のコードが実行される前にブロックですぐに有効になりますが、letor constステートメントまでアクセスできません。
var a = 0;
console.log(a);
if (true)
{
console.log(a); // ReferenceError: a is not defined
let a = 1;
console.log(a);
}
ブロックの外側からconsole.logにアクセスする代わりに、2番目が失敗することに注意してくださいa。
window)windowオブジェクトは、非常に、非常に性質に乱れます。可能な限り、混乱に追加しないことを強くお勧めします。代わりに、シンボルを小さなパッケージにまとめ、最大で 1つのシンボルをwindowオブジェクトにエクスポートします。(私は頻繁にエクスポートしない任意のシンボルをwindowあなたの記号が含まれているために、すべてのコードを格納する機能を使用することができます。オブジェクト)、そしてあなたのような場合、その関数は匿名になります
(function() {
var a = 0; // `a` is NOT a property of `window` now
function foo() {
alert(a); // Alerts "0", because `foo` can access `a`
}
})();
その例では、関数を定義して、すぐに(()最後に)実行します。
このように使用される関数は、スコープ関数と呼ばれることがよくあります。スコープ関数内で定義された関数は、スコープ関数で定義された変数にアクセスできます。これは、それらがそのデータのクロージャだからです(参照:貧弱な小さなブログでは、クロージャは複雑ではありません)。
window['a']=0ウィンドウをマップとして使用していることを明確にするにはどうすればよいですか?あるwindow一部のブラウザでは、これを許可し、使用するために私を強制しないように特別なwindow.a?
window.a = 0;ブラウザー環境でのみ機能し、慣例によってのみ機能します。名前付き変数へのグローバルオブジェクトのバインドはwindowES仕様にないため、たとえばV8やNode.jsでは機能しませんが、this.a = 0;(グローバル実行コンテキストで呼び出されると)仕様で指定されているため、どの環境でも機能します。グローバルオブジェクトが存在する必要があります。Off-topicセクションのようにIIFEでコードをラップする場合は、this名前付きパラメーターとして渡すwindowかglobal、グローバルオブジェクトへの直接参照を取得できます。
var a = 0;自動的にグローバルオブジェクトのプロパティになります。var b = 0;関数宣言内で宣言した場合、それはいくつかの基になるオブジェクトのプロパティにもなりますか?
シンプルに保つ:
a = 0
上記のコードはグローバルスコープ変数を提供します
var a = 0;
このコードは、現在のスコープで、およびその下で使用される変数を提供します
window.a = 0;
これは通常、グローバル変数と同じです。
a して、現在のスコープ。あなたはできる。また、「グローバル変数」の使用は少しずれています。「グローバル変数」と言う2つの場所は、言わない場所よりもグローバルではありません。
<title>Index.html</title>
<script>
var varDeclaration = true;
noVarDeclaration = true;
window.hungOnWindow = true;
document.hungOnDocument = true;
</script>
<script src="external.js"></script>
/* external.js */
console.info(varDeclaration == true); // could be .log, alert etc
// returns false in IE8
console.info(noVarDeclaration == true); // could be .log, alert etc
// returns false in IE8
console.info(window.hungOnWindow == true); // could be .log, alert etc
// returns true in IE8
console.info(document.hungOnDocument == true); // could be .log, alert etc
// returns ??? in IE8 (untested!) *I personally find this more clugy than hanging off window obj
すべての変数がデフォルトでオフになっているグローバルオブジェクトはありますか?例: 'globals.noVar宣言'
window.*宣言を使用するための明確なガイド。この宣言は、コードのコピーアンドペーストに対して最も安全に見え、また明確です。
優れた答えにBassed TJクラウダー:(オフトピック:避ける乱雑window)
これは彼のアイデアの例です:
HTML
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="init.js"></script>
<script type="text/javascript">
MYLIBRARY.init(["firstValue", 2, "thirdValue"]);
</script>
<script src="script.js"></script>
</head>
<body>
<h1>Hello !</h1>
</body>
</html>
init.js(この回答に基づく)
var MYLIBRARY = MYLIBRARY || (function(){
var _args = {}; // private
return {
init : function(Args) {
_args = Args;
// some other initialising
},
helloWorld : function(i) {
return _args[i];
}
};
}());
script.js
// Here you can use the values defined in the html as if it were a global variable
var a = "Hello World " + MYLIBRARY.helloWorld(2);
alert(a);
これがplnkrです。それが役に立てば幸い!
グローバルスコープでは、意味上の違いはありません。
ただしa=0、値を宣言されていない変数に設定するため、実際には避けてください。
また、クロージャを使用して、グローバルスコープをまったく編集しないようにします。
(function() {
// do stuff locally
// Hoist something to global scope
window.someGlobal = someLocal
}());
常にクロージャを使用し、絶対に必要な場合は常にグローバルスコープに引き上げます。とにかく、ほとんどの通信で非同期イベント処理を使用する必要があります。
@AvianMoncellorが言及したようにvar a = foo、ファイルスコープのグローバルを宣言するだけのIEバグがあります。これは、IEの悪名高い壊れたインタープリターの問題です。このバグはおなじみのように聞こえるので、おそらく本当です。
だから固執する window.globalName = someLocalpointer
deletevar
var。それらはまったく同じメカニズムであり、実際に同じ結果をもたらします。:-)
varスコープの停止にジャンプすることを言及するのを忘れていました。