JavaScript 巻き上げについて

More than 3 years have passed since last update.


妹から「巻き上げについて説明して!」(妹いないけど)って言われたのでわかりやすいコードを書くよ。

まずはこれ。

var global = "foo";

var hoge = function(){
console.log(global);
var global = "bar";
console.log(global);
}

hoge();

結果は


// undefined
// bar

まず、foo が表示されて次に bar が表示されると思ったそこの妹思いのエンジニアさん、はっきりと申し上げておきますが妹ってのは空想上の生き物です。


foo を表示させるには

一発目の console.log(global) に this を付け加えてやる。

var global = "foo";

var hoge = function(){
console.log(this.global);
var global = "bar";
console.log(global);
}

hoge();

すると

// foo

// bar

に。


え、そうだったっけという人向けに

this が無くても、これで foo は表示される。

var global = "foo";

var hoge = function(){
console.log(global);
}

hoge();

何が違うのかっていうと、「同一スコープ内で同じ変数名の変数が宣言されていない」っていうこと。

逆に、同一スコープ内で同じ変数名の変数があると「巻き上げ」られて、「その変数は宣言済み」として認識されるよ

なので最初のコードは

var global = "foo";

var hoge = function(){
var global = undefined;
console.log(global);
var global = "bar";
console.log(global);
}

hoge();

と同じ振る舞いになる。


こんな自体に陥らないために

使用する変数は前もって宣言しておくのがベストだそうです。

それと、普段から妹へはお菓子(たけのこの里、カール['カレーがけ'])を振る舞っておけばこんなことにはなりませんね