ホームページ >ウェブフロントエンド >jsチュートリアル >Javascript変数のスコープとスコープチェーンの詳しい解説_JavaScriptスキル

Javascript変数のスコープとスコープチェーンの詳しい解説_JavaScriptスキル

WBOY
WBOYオリジナル
2016-05-16 16:06:151109ブラウズ

ここ数年間、私は JS をあまり学習していませんでしたが、たまたま週末に時間があったので、Rhinoceros の有名な本である「The Authoritative Guide to JS」を購入しました。 、JS について詳しく調べました。この本を買った第一印象は、かなり分厚いのですが、後半の半分はただの参考書です。

1: 範囲

変数について話すとき、最初に話すべきことは間違いなくスコープです。JS のスコープに慣れていないからこそ、オブジェクト指向のスコープは常に無視されます。これは習慣的に行われていますが、すべてのコピーが可能であるわけではありません。そこで、次の疑問が生じます。これは、もちろん、ウィンドウ A の名前フィールドで定義されている場合、関数のスコープです。 name フィールドの関数スコープは window です。つまり、関数 ctrip が wi​​ndow の下で定義され、その中で名前が定義されている場合、新しく定義された名前は、window の下でのみ共通になります。 ctrip 関数ですが、たとえば window では古い名前が引き続き一般的です。

写真から 2 つの点がわかります:

1: window に名前を定義した後、function にも同じ名前を定義できます。これは C# では考えられません。

2: JS では自分のスコープしか認識しないので、最初の「2 番目」が表示されるのは何も不思議なことではないと思われるかもしれません。パーサーが ctrip を実行すると、最初に ctrip 内のすべてのローカル変数が検索され、その後、var name="second" という文の定義が実行されます。 . 以下のステートメントを置き換えてみましょう。

ctrip 関数では、最初の console.log 出力が未定義であることがわかります。この結果から、最初にローカル変数名を収集することが行われたことが確認できます。なぜ「2 番目」にならなかったのか疑問に思う人もいるかもしれません。これは、初期化操作をステートメントごとに実行する必要があるためです。そのため、 ctrip 関数で console.log(name) が実行されるとき、パーサーは未割り当ての変数名があることのみを認識するため、 console のときは未定義になります。

2: スコープチェーン

また、上記の例から、関数内で定義された変数のスコープは関数のスコープ内のみであることが明確にわかります。同時に、上記の例は単なるネスト層とウィンドウであることもわかります。これは ctrip 関数である大きな関数です。同じ原理を 3 レベルや 4 レベルなどの複数レベルのネストに拡張することもできます。 。 。 。 N層、これらの層は鎖構造を形成します。

図からわかるように、この場合、ctrip でプレーン関数を定義しました。出力結果は、それぞれのスコープ内にのみ表示されます。 🎜>

内で有効になりますが、ある日、plane の関数を定義する際に、var name="third" に var を書き忘れてしまいました。飛行機内 >

名前の価値は何ですか? 1番目ですか、2番目ですか?


var name="first";
関数 ctrip(){
var name="2 番目";
関数プレーン(){
name="3 番目";
console.log(名前);
}
平面();
console.log(名前);
}
ctrip();
console.log(名前);

ここからは、スコープチェーンを本当に理解できているかどうかのテストです。よく考えてみると、plane 関数の name="third" までコードを実行すると、何も存在しないことがわかります。プレーン関数のローカル変数名。このコードはビッグ関数 ctrip にもあるため、パーサーは ctrip 関数に戻って名前を検索し、この時点で実際に名前が存在することがわかります。 ctripの名前は「サード」に変更されます。

別の日、私は飲みすぎて、また愚かな行動をしてしまいました。plane 関数を定義するときに、間違って name="third" を nam="third" と書きました。これはアルコールの質問と言えます。

それは私のコードの問題ではありません。では、この時点でパーサーは何をすべきでしょうか?同様に、バックトラックしたときに ctrip が存在しないことがわかり、トップレベルのウィンドウにバックトラックしたところ、まだ存在しないことがわかりました。

この時点では、チェーン全体に値が存在せず、値が割り当てられているため、エラーを報告することはできません。単純に定義します。窓の中で暗黙的にあなたのために🎜>

nam 変数。この時点では、nam は実際にはグローバル変数です。ウィンドウの最上位コンソールで nam を確認できます。

変数についてはあまりにも多くのことがあるだけで、驚くべきことは何もありません。理解できても面白くはありません。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。