web-dev-qa-db-ja.com

JavaScript 'let'グローバル変数は、グローバル 'var'とは異なり 'window'のプロパティではありません

グローバルvarが次のように定義されているかどうかを確認するために使用しました:

if (window['myvar']==null) ...

または

if (window.myvar==null) ...

var myvar

Letに切り替えようとしているので、これはもう機能しません。

var myvar='a';
console.log(window.myvar); // gives me a
let mylet='b';
console.log(window.mylet); // gives me undefined

質問:グローバルletを使用して、varオブジェクトのwindowを使用して何かを定義できた場合、どこで確認できますか?

より一般的には
var myvar='a' に相当 window.myvar='a'
グローバルレベルでletvarは同じ/動作していると人々が言うのを聞きますが、これは私が見ているものではありません。

13
Fai Ng

グローバルレベルでは、letとvarは同じ/振る舞うと人々が言うのを聞きますが、これは私が見ているものではありません。

ええ、はい、いいえ。あなたの質問に答えるために、大多数の場合、letvarはグローバルに宣言されたとき同じですが、いくつかの違いがあります。

説明するには:グローバル環境レコードは、JSがコードのすべてのロジックとメモリの値を保持している場所です。ただし、このグローバル環境レコードは、実際にはオブジェクト環境レコードおよび宣言的環境レコードをカプセル化した複合です。

もう少し説明:

宣言型環境レコードは、バインディングを内部データ構造に格納します。何らかの方法でそのデータ構造を保持することは不可能です(関数のスコープについて考えてください)。

オブジェクト環境レコードは、実際のJSオブジェクトをデータ構造として使用します。オブジェクトのすべてのプロパティがバインディングになり、その逆も同様です。グローバル環境には、「バインディングオブジェクト」がグローバルオブジェクトであるオブジェクト環境レコードがあります。これはRealmであり、ほとんどの場合windowオブジェクトです。

したがって、ECMA仕様によれば、FunctionDeclarationsGeneratorDeclarations、およびVariableStatementsglobal環境のオブジェクト環境レコードにバインディングを作成します。

他のすべての宣言(つまり、constおよびlet)は、グローバルオブジェクトに基づいていないグローバル環境のdeclarative環境レコードに格納されます。それらはまだ変数を宣言していますが、VariableStatementではありません。

TL; DR:どちらもグローバルですが、varsはwindowオブジェクトに格納され、letsは宣言できない環境に格納されます参照してください(関数の外部から関数スコープ内の変数にアクセスできないのと同じです)。グローバルに宣言すると、両方のステートメントの使用法はほぼ同じになります。

20
joh04667