1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

岩手県立大学Advent Calendar 2019

Day 9

JavaScriptの巻き上げをサンプルコードで理解する

Last updated at Posted at 2019-12-08

この記事は、岩手県立大学 Advent Calendar 2019 9日目の記事です。

1. はじめに

こんにちは。岩手大学のTakuyaHanadaです。

今回は、初Advent Calendarということで(関係はないです)、JavaScriptの巻き上げについてアウトプットしていきます!

間違い等あれば、教えてくださると勉強になります。

2. 巻き上げとは

  • varを使って宣言された変数
  • functionを使って宣言された関数

が、現在のスコープで宣言前でも使えること。

3. よくわかんないから実際のコードを見て学ぶ

以下のサンプルコードの出力を予想しながら見てみてください!

※ 出力結果はnodeで動作させた場合のものです。

3-1. サンプルコード1

sample1.js
var hoge = 'おはよう靴下';
console.log(hoge);
sample1.jsの出力
おはよう靴下

これは当たり前ですね。

sample1.jsの実際の動作コード
var hoge = 'おはよう靴下';
console.log(hoge);

3-2. サンプルコード2

sample2.js
console.log(hoge);
var hoge = 'おはよう靴下';
sample2.jsの出力
undefined

巻き上げが起こります。

はい?と思うかもしれません。これが巻き上げです。

巻き上げが起こり、var hogeが一番上(正確に言うと、宣言されたスコープの一番上)に来ています。

sample2.jsの実際の動作コード
var hoge;  // 巻き上げが起こっている
console.log(hoge);
hoge = 'おはよう靴下';

3-3. サンプルコード3

sample3.js
console.log(fuga);
let fuga = 'おはよう靴下';
sample3.jsの出力
ReferenceError: Cannot access 'fuga' before initialization

巻き上げは起こりません。

ん?と思うかもしれません。

しかし、巻き上げが起こるのはvarで宣言した場合のみです。

なので、この場合はコードの通りに動きます。(constの場合もletと同様です)

sample3.jsの実際の動作コード
console.log(fuga);
let fuga = 'おはよう靴下';  // let で定義しているため、巻き上げが起こらない

3-4. サンプルコード4

sample4.js
if (hoge !== 'おはよう') {
  var fuga = '靴下';

  if (fuga === '靴下') {
    var hoge = 'おはよう';
  }
}

if (hoge === 'おはよう') {
  console.log(hoge + fuga);
}
sample4.jsの出力
おはよう靴下

巻き上げが起こります。

これは、サンプルコード2と同様です。

巻き上げが起こり、var hogevar fugaが一番上に来ています。

sample4.jsの実際の動作コード
var hoge;  // 巻き上げが起こっている
var fuga;  // 巻き上げが起こっている
if (hoge !== 'おはよう') {
  fuga = '靴下';

  if (fuga === '靴下') {
    hoge = 'おはよう';
  }
}

if (hoge === 'おはよう') {
  console.log(hoge + fuga);
}

3-5. サンプルコード5

sample5.js
function fn() {
  console.log('fnの中のhoge', hoge);
  var hoge = 'おはよう靴下';
}

fn();
console.log('fnの外のhoge', hoge);
sample5.jsの出力
fnの中のhoge undefined
ReferenceError: hoge is not defined

巻き上げが起こります。

このサンプルコードは、混乱するかもしれません。

しかし、巻き上げは

varを使って宣言された変数が、現在のスコープで宣言前でも使えること。

なので、現在のスコープ(サンプルコード5の場合はfn)でしか使うことができません。

つまり、以下のように動いています。

sample5.jsの実際の動作コード
function fn() {
  var hoge;  // 巻き上げが起こっている
  console.log('fnの中のhoge', hoge);
  hoge = 'おはよう靴下';
}

fn();
console.log('fnの外のhoge', hoge);

3-6. サンプルコード6

sample6.js
fn();

function fn() {
  console.log('おはよう靴下');
}
sample6.jsの出力
おはよう靴下

巻き上げが起こります。

これは関数の巻き上げです。関数もvarと同様に巻き上げが起こります。

sample6.jsの実際の動作コード
function fn() {  // 巻き上げが起こっている
  console.log('おはよう靴下');
}
fn();

3-7. サンプルコード7

sample7.js
fn();

const fn = () => {
  console.log('おはよう靴下');
};
sample7.jsの出力
ReferenceError: Cannot access 'fn' before initialization

巻き上げは起こりません。

これはサンプルコード3と同様です。

constfnという変数を定義しているため、このようになります。

sample7.jsの実際の動作コード
fn();

const fn = () => {  // 巻き上げは起こらない
  console.log('おはよう靴下');
};

3-8. サンプルコード8

sample8.js
fn();

var fn = () => {
  console.log('おはよう靴下');
};
sample8.jsの出力
TypeError: fn is not a function

巻き上げが起こります。

これは、サンプルコード7と同様にfnという変数を定義していますが、varを使っているため、巻き上げが起こります。

sample8.jsの実際の動作コード
var fn;  // 巻き上げが起こっている
fn();

fn = () => {
  console.log('おはよう靴下');
};

4. おわりに

以上がJavaScriptの巻き上げでした。

var, functionを使う際には気をつけましょう。

5. 参考文献

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?