Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
19
Help us understand the problem. What are the problem?

posted at

updated at

【JavaScript】 変数とスコープについて。

概要

var、let、constの3種類の違いと、それぞれのスコープ内の挙動に関してまとめました。
先に押さえておきたい部分を説明した後に、スコープの説明に入ります。

目次

  • 変数
    • 変数宣言
      • 変数宣言の種類
  • 初期化と代入
    • 初期化
    • 代入
  • スコープ
    • スコープの種類
      • グローバルスコープ
      • ローカルスコープ
        • 関数スコープ
        • ブロックスコープ
    • スコープチェーン

変数

扱いたいデータを格納し、何度でも再利用できるオブジェクト。

変数宣言

変数をプログラム上に定義すること。

変数宣言の種類

変数宣言には以下の種類が存在し、それぞれ挙動が異なる。

var(バー)

古くから使われているお馴染みの変数宣言、jQueryのサンプルなどもほとんどvarが使用されている。
実案件でも世に溢れているので必ず理解していないとまずい。

let(レト)

ES6から登場した変数宣言、代入可能なのでvarに近い感覚で使える。

const(コンスト)

ES6から登場した変数宣言、再代入不可なので、定数の感覚で使える。
※let、constはES6だけどIE11に対応しているのでそのまま使用できる。

初期化と代入

初期化

変数宣言と同時に、値・文字列を代入すること。

var x = 0;

代入

すでに定義されている変数に、値・文字列を格納すること。

var x = 0;
x = 1;

varにおける注意点

初期化が何度でも可能であるので、代入と混乱しないように注意したい。

■間違い
var x = 0;
var x = 1;

このように初期化して上書きしてもエラーにならない、これをlet、constで実行するとエラーになる。

■正しい
var x = 0;
x = 1;

スコープ

定義した変数を参照できる範囲。

スコープの種類

グローバルスコープとローカルスコープが存在する、さらにローカルスコープとして関数スコープとブロックスコープが存在する。

グローバルスコープ

scriptタグ内の最も外側のエリア、ここで宣言された変数はwindowオブジェクト直下に格納される。
このエリアに定義されている変数をグローバル変数と呼ぶ。

var x = 0;
console.log(window.x);
// 0

ローカルスコープ

グローバルスコープの内側で、より参照範囲を絞ったスコープ。
ローカルスコープとして関数スコープ、ブロックスコープが存在する。
このエリアに定義されている変数をローカル変数と呼ぶ。

関数スコープ

関数内に存在するスコープ。

function myFunc() {
    var x = 0;
    console.log(x);
    // 0
};
myFunc();
console.log(x); // ReferenceError
引数がある場合の注意点

関数において、引数はローカル変数である。
外側のスコープを見ているのかと思えば、引数がある場合は同スコープ内の変数として扱われるので注意。

var x = 0;
function myFunc(x) {
  console.log(x);
};
myFunc(1);
// 1

ブロックスコープ

ブロック内に存在するスコープ
※変数宣言はlet、constのみ対応。

{
    let x = 0;
    console.log(x);
    // 0
}
console.log(x); // ReferenceError

varはブロックスコープに対応していない。

{
    var x = 0;
    console.log(x);
    // 0
}
console.log(x);
// 0
ローカルスコープ内での変数宣言対応を一覧表にしました。
関数スコープ
var let const
ブロックスコープ
var let const
×

※スコープに適応している場合○、しない場合×

例外ケース

for文の()にもローカルスコープに等しい挙動がある、for文のブロック外からは参照できない。


for(let x = 0;x < 10;x++){
    console.log(x);
    // 0〜9
}
console.log(x);
// ReferenceError

スコープチェーン

スコープチェーンとは、複数生成されたオブジェクトに対して、それらの順序をリスト化したものである。
生成されたオブジェクトにスコープが存在するので、変数はどの順序で参照していくのか仕組みを理解する必要がある。
スコープチェーンの仕組みを知らないと、特にスコープがネストされている際に変数の参照を正しく判別できない。

以下のコードと文脈で説明します。

function outerFunc() {
  var x = 0;

  function innerFunc() {
    var z = 2;
    console.log(x);     
    console.log(y);
    console.log(z);
  };
  innerFunc();
};

var y = 1;
outerFunc();
// 0
// 1
// 2
  • xはinnerFunc内を探したが、存在しなかったので一つ上のouterFunc内を探しに行き拾えた。
  • yはinnerFunc内、outerFunc内を順に探したが存在しなかった、次にグローバルスコープ内を探しに行き拾えた。
  • zはinnerFunc内に存在したのでそのまま拾えた。

このように近くのスコープから順に辿り探していく仕組みである。

以上となります、ご覧戴きありがとうございました。
間違い等のご指摘あれば、よろしくお願いします。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
19
Help us understand the problem. What are the problem?