🐻

JavaScriptのスコープとコンテキスト

2023/09/06に公開

序論

JavaScriptにおけるスコープとコンテキストは、初学者にとっては避けて通れない重要なテーマである。これらを理解しないと、コードが意図しない挙動を示す可能性が高くなる。この記事は、スコープとコンテキストについての基本概念をまとめ、今後の学習や実践に活かす振り返りの一助としたい。

目次


スコープ

グローバルスコープ

JavaScriptのプログラム全体でアクセスできる変数や関数が存在するスコープである。ブラウザではこれがwindowオブジェクトとして現れる。グローバル変数や関数は便利であるが、多用すると名前の衝突や未意図の挙動を引き起こす可能性がある。初学者はこの点に注意が必要である。

var globalVar = "I am global!";

スクリプトスコープ

基本的にはグローバルスコープとほぼ同じだが、サーバーサイド環境(例:Node.js)では、各ファイルが独自のスクリプトスコープを持つ。これは、クライアントサイド(ブラウザ)とサーバーサイドでスコープが異なるという注意点がある。

// Node.jsの場合
exports.myFunction = function() {
  console.log('Hello from myFunction');
};

レキシカルスコープ

レキシカルスコープは、コードが物理的にどの位置に書かれているかによって、その内部で参照できる変数が決まる。このスコープの理解は、特に関数内の関数(内部関数)を使いこなす上で重要である。

function outerFunction() {
  let outerVariable = "I am from outer function";
  
  function innerFunction() {
    console.log(outerVariable);
  }

  innerFunction();
}

outerFunction();

スコープチェーン

スコープチェーンとは、あるスコープが他のスコープに「包まれて」いる状態を指す。これにより、内側のスコープから外側のスコープの変数や関数にアクセスすることができる。

クロージャ

クロージャは、関数とその関数がアクセスする外部変数との「セット」である。これを用いると、プライベート変数を作成することが可能になる。また、動的な関数を生成する際にも利用される。

// プライベート変数の利用例
function incrementFactory() {
  let num = 0;

  function increment() {
    num += 1;
    console.log(num);
  }

  return increment;
}

const increment = incrementFactory();
increment();

即時関数

即時関数は、定義された瞬間に実行される関数である。このテクニックは、変数のスコープを限定してコードの独立性を高める場合に用いられる。

(function() {
  console.log('This function runs immediately');
})();

コンテキスト

グローバルコンテキスト

すべてのグローバル変数、関数などはこのコンテキスト内で定義され、どこからでもアクセスできる。ブラウザではwindowオブジェクト、Node.jsではglobalオブジェクトがこれに該当する。

関数コンテキスト

関数が呼び出されるたびに新しい関数コンテキストが生成される。この中では、thisキーワードや関数スコープ内で定義された変数、引数、内部関数などが存在する。

function myFunction() {
  console.log(this);
}
myFunction();

まとめ

スコープとコンテキストの理解はコードの質を高め、エラーを避けるために必要不可欠である。この振り返りを通じて、スコープとコンテキストの基本的な概念と使い方を確認した。特にレキシカルスコープやクロージャについては、より高度なJavaScriptのプログラミングにおいて頻繁に遭遇するテーマであるため、しっかりと理解しておきたい。

Discussion