JavaScriptのスコープとは?グローバル・ローカル・レキシカルスコープの違いを徹底解説
この記事では、JavaScriptにおけるスコープの仕組みと、グローバルスコープ・ローカルスコープ・レキシカルスコープという3種類の違いについて、実例コード付きでわかりやすく解説します。
スコープ(Scope)とは、関数や変数にアクセスできる範囲(コンテキスト)のことです。JavaScriptのスコープには、主に以下の3種類があります。
- グローバル変数: コードブロックの外側で宣言された変数
- ローカル変数: コードブロックの内側で宣言された変数
覚えておきたいポイント: 関数は、自分の外側で定義された変数や関数にはアクセスできます。しかし、他の関数の内側で定義された変数にはアクセスできません。
この点については、後ほどコード例を見ればすぐに理解できるでしょう。
グローバルスコープ(Global Scope)
グローバルスコープ上にある変数や関数は、他の関数の中からでも自由にアクセスできます。
// グローバルスコープ
let dogBreed = "Labrador"
let getDogBreed = function() {
// dogBreedはグローバルスコープにあるためアクセス可能
console.log(dogBreed)
// "Labrador"
}
// 関数を実行
getDogBreed()
これは、関数の中に入れ子になった関数の場合も同様です。
// グローバルスコープ
let dogBreed = "Labrador"
let getDogBreed = function() {
// 関数の中の関数
let getDogBreedFromGlobalScope = function() {
// グローバルスコープのdogBreedにアクセス
console.log(dogBreed)
// "Labrador"
}
// 内側の関数を実行
getDogBreedFromGlobalScope()
}
// 関数を実行
getDogBreed()
ローカルスコープ(Local Scope)
ローカルスコープを持つ変数や関数は、そのスコープ自身の内側からしかアクセスできません。
let getDogBreed = function() {
// ローカルな変数スコープ
let dogBreed = "Labrador"
// ローカル変数なので関数内からアクセスできる
console.log(dogBreed)
// "Labrador"
}
変数dogBreedはローカルスコープを持つため、そのスコープ内、つまり波括弧{ .. }の中からしかアクセスできません。
次に、先ほどと同じコードを使って、今度はconsole.log(dogBreed)をローカルスコープの外側(=グローバルスコープ)に移動してみます。
let getDogBreed = function() {
// ローカルな変数スコープ
let dogBreed = "Labrador"
}
// ローカルスコープの変数にアクセスしようとする
console.log(dogBreed)
// Uncaught ReferenceError: dogBreed is not defined
すると「dogBreed is not defined(dogBreedは定義されていません)」という参照エラー(ReferenceError)が発生します。これは、グローバルスコープからローカルスコープの変数を参照しようとしたために起こるものです。
レキシカルスコープ(Lexical Scope)
関数をネストする(関数の中に関数を入れる)と、親関数(一番外側の関数)内の変数や関数には、内側の関数からアクセスできます。この仕組みをレキシカルスコープと呼びます。
ただし、逆は成り立ちません。親(外側)の関数から、内側の関数内にある変数や関数にアクセスすることはできません。言葉だけではイメージしにくいため、実際のコード例で確認してみましょう。
// グローバルスコープ
let animals = function() {
// レキシカルスコープ
let dogBreed = "Labrador"
// ネストされた関数
let getAnimals = function() {
// dogBreedはレキシカルスコープにあるためアクセス可能
console.log(dogBreed)
// "Labrador"
// こちらはローカルスコープの変数
let catBreed = "Persian"
console.log(catBreed)
// "Persian"
}
// ネストされた関数を実行
getAnimals()
// dogBreedはレキシカルスコープ内にあるため正常に表示される
console.log(dogBreed)
// "Labrador"
// catBreedはgetAnimals()関数のローカル変数のため、ここでは参照できない
console.log(catBreed)
// Uncaught ReferenceError: catBreed is not defined
}
animals()
まとめ
- グローバルスコープ: プログラム全体からアクセスできる最上位のスコープ
- ローカルスコープ: 関数などのブロック内でのみ有効なスコープ
- レキシカルスコープ: 内側の関数から外側の関数の変数にアクセスできる仕組み(逆向きのアクセスは不可)
スコープの仕組みを正しく理解することで、意図しない変数の衝突やエラーを防ぎ、保守性の高いコードを書けるようになります。
-
OperaでJavaScriptを有効にする方法【初心者向けガイド】
OperaでJavaScriptを有効にする手順OperaブラウザでJavaScriptを有効にしたい場合は、以下の手順に従って設定を行ってください。1. 設定画面を開くまず、Operaブラウザを起動し、画面左上にあるメニューボタンをクリックします。表示されたメニューの中から「設定(Settings)」を選択してください。2. 「javascript」を検索する設定画面が開いたら、ページ上部にある検索ボックス(設定の検索)に「javascript」と入力します。3. JavaScriptの許可設定を変更する検索を実行すると、JavaScriptに関するオプションが表示されます。ここで「サイトが
-
JavaScriptでメソッドを借りる方法とは?call()・apply()・bind()の使い方を解説
JavaScriptでは、call()、apply()、bind() の3つのメソッドを使うことで、他のオブジェクトが持つメソッドを「借りて」実行することができます。このテクニックは「メソッドの借用(Method Borrowing)」と呼ばれ、コードの再利用性を高めるために広く活用されています。call()・apply()・bind() の違いcall():第1引数に this として渡したいオブジェクトを指定し、残りの引数はカンマ区切りで個別に渡します。呼び出し時に即座に実行されます。apply():call() とほぼ同じですが、引数を配列(または配列風オブジェクト)としてまとめて渡す点