##そもそも、スコープとは
プログラミングにおけるスコープ(英: scope, 可視範囲)とは、ある変数や関数などの名前(識別子)を参照できる範囲のこと。
(参照:wikipedia https://ja.wikipedia.org/wiki/%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%97)
##スコープを使うことでできること
・範囲外のものは参照をさせないような設計ができる(変数をスコープの外では変更できないような、安全性を確保)
・スコープがあることにより、関数名や変数名等同じものを使用してもスコープの内外で有効な範囲が変わってくるので、コード全体の命名が簡潔に済む
##スコープの種類
グローバル変数とローカル変数の二種類に分かれる。
グローバル変数 | ローカル変数 |
---|---|
関数の外(トップレベル)で宣言した変数 | 関数の中で宣言した変数, 関数の仮引数 |
プログラム全体から参照できる | その関数の中でのみ参照できる |
##グローバルスコープ
プログラムのどこからでもアクセス可能。
JavaScript においては、一般的にすべてのコードが実行されている Web ページがグローバルスコープとなる。
aとbは関数からでも、ブロック内でもどこでも呼び出せる。
##ローカルスコープ
ローカルスコープは二種類あり、関数スコープ
とブロックスコープ
に分かれる。
##関数スコープ
関数スコープはその名前の通り、関数ごとに作られるスコープ。
↑関数内で定義したhelloに対して、関数の外から呼び出しをしようとすると、上記のようなエラーが出てしまう。
↑こちらは関数内で定義したものを関数内で呼び出している為、エラーの表示がなく、結果もしっかりと"hello world"の文字列が取得できました。
このように関数内で定義したものは関数内でしか実行できないものを関数スコープと呼ばれています。
##ブロックスコープ
ブロックスコープも関数スコープと同じくローカルスコープの仲間で、if文やfor文と組み合わせることが多いです。
↑ブロック内で宣言しているinBlockはブロックの外から呼び出してもスコープ外の為、未定義エラーが出てしまう。
↑こちらも同様にfor文の外で回数を出力しようとすると、未定義エラーが出てしまう。
##上記のスコープで注意する点
####letとvarの違い
変数宣言をする際、letとvar(とconst)があるが、それぞれスコープに違いがある。
↑このようにブロックスコープを定めても、letはブロックごとに読み取りの制限をすることが出来ているのですが、varを使用している場合ブロック内のfoo
を読みとってしまっている為、外部から意図しない値に書き変わってしまいバグが発生する可能性がある。
また、varにはホイスティングと呼ばれる機能があり、関数の内部で宣言されている変数は、その関数の先頭で宣言されたものと見なされるというものです。
このようなサンプルコードではすぐ近くにあるので気づけますが、関数の行数が多い場合foo
がトップレベルのfooと勘違いしてしまう可能性もあり、さらにコードがエラーを出さない為、対処が大変になってしまう可能性があります。
###最後に
Javascriptに苦手イメージがあり、ほとんど勉強をしてこなかったのですが、業務で取り扱う機会が多いので基礎から勉強しようと思いスコープを題材に取り上げました。
まだまだ、わからないことだらけなので、整理しながら勉強をしていきます。