2

存在しない変数にアクセスしようとすると javascript が例外をスローするのに、オブジェクトに存在しないプロパティにアクセスしようとすると javascript がundefined値を返すのはなぜですか?

たとえば、次の場合はundefined値が返されます。

function Foo(){
    console.log(this.bar);
}

Foo();

しかし、この別の例では、javascript が例外をスローします。

function Foo(){
    console.log(bar);
}

Foo();

ReferenceError: バーが定義されていません

4

3 に答える 3

3

JavaScriptのすべてのオブジェクトは辞書であり、他の言語ではマップとも呼ばれるため、キーによる値へのアクセスthis.barと同等です。this['bar']ほとんどの言語(Javaなど)では、、を返すかnull、このスロットがまだ存在しない場合は、例外やその他の副作用に対処することなく、条件付きでこのスロットを作成できます。NULLundefined

ただし、console.log(bar)のコンテキストを指定せずに記述した場合bar、戻りundefined値が意味的な意味を持つ合理的なパターンを作成することは不可能です。window複数のコンテキストがあり、ブラウザのグローバルコンテキストのように動的なコンテキストもbarあり、実行時に定義される可能性があるため、(JavaやC ++とは対照的に)コンパイル時のエラーになることはありません。したがって、変数名を解決できない場合、実行時例外がスローされます。

于 2012-09-18T21:37:34.433 に答える
1

プロパティの解決は、識別子の解決とは根本的に異なります。些細な答えは、ECMA-262 では、存在しない変数を読み取ろうとするとエラーがスローされると指定されていますが、存在しないオブジェクト プロパティを読み取ろうとするとエラーがスローされず、特別な未定義の値が返されるだけです。

その理由を知るには、ECMA-262 のベースとなる JavaScript を最初に開発した Brendan Eich に聞く必要があります。しかし、妥当な推測として、ブレンダンは次のようなことをするのではなく、JavaScript を緩い型付けの単純な言語にしたいと考えていました。

if ( 'foo' in obj) {
  /* do something with obj.foo */
}

初めてプロパティにアクセスするたびに、言語は未定義のプロパティへのアクセスを許容するようになりました。

一方、変数に同じアプローチを適用すると、解決するよりも多くの問題が発生するためtypeof、識別子が存在するかどうかを確認するために使用できます。

if (typeof foo != 'undefined') {
  /* ok to use foo */
}

それ以外の場合、プロパティと識別子の解決は非常に似ています。違いは、最初は内部[[Prototype]]オブジェクトの文字列 (継承チェーン) に沿ってオブジェクトから進み、最後にnullオブジェクトに進むのに対し、変数解決は外部コンテキスト (スコープ) に属する同様のオブジェクトの文字列に沿ってローカル変数オブジェクトから進むことです。 chain) をグローバル オブジェクトに追加します。

于 2012-09-18T23:19:17.900 に答える
0
function Foo(){
    console.log(window.bar);
}

Foo();

また、あなたに与えますundefined

this.bar意味this["bar"]

于 2012-09-18T21:45:20.430 に答える