はじめに
先日、JavaScriptにおける「巻き上げ」について調べました。
この「巻き上げ」について、TypeScriptでは挙動が違うようです。
「変数」の巻き上げ
まず、変数の巻き上げです。
【JavaScriptの場合】
-
var
で宣言し、宣言前に呼び出すとundefined
を返す -
const
で宣言し、宣言前に呼び出すとReferenceError
を発生させる
console.log(str_var) //undefined
console.log(str_const) //ReferenceError
var str_var = 'var'
const str_const = 'const'
【TypeScriptの場合】
var
の場合でもちゃんと指摘してくれるんですね!偉い!var
を使うことはないけど・・・
const
に対しても、「宣言前・初期化前(割当前)に呼び出してますよ!」って教えてくれてますね。ここはJavaScriptからの正当進化という感じ。
「関数」の巻き上げ
JavaScript / TypeScriptにおいて、関数の定義方法は主に2種類あります。
関数宣言と関数式です。
// 関数宣言
function hello() {
console.log('hello!')
}
// 関数式
const hello = function() {
console.log('hello!')
}
// 関数式(アロー関数)
const hello = () => {
console.log('hello')
}
【JavaScriptの場合】
- 関数宣言の場合、定義前に呼び出すと「問題なく実行される」
- 関数式の場合、定義前に呼び出すと
ReferenceError
を返す
hello_dec(); // 出力:hello dec!
hello_ex(); // ReferenceError
function hello_dec() {
console.log('hello dec!')
}
const hello_ex = function() {
console.log('hello ex!')
}
// "dec"は"declaration(宣言)"・"ex"は"expression(式)"を表す
【TypeScriptの場合】
JavaScriptとほぼ変わらないですね!実行前にわかるかどうか。
関数宣言の場合はTypeScriptでも弾かないんですね。
おわりに
JavaScriptでもTypeScriptでも「関数宣言は巻き上げられる(定義前の呼び出しが可能)」なので、宣言前の呼び出し許さないマンの方は、関数宣言ではなく関数式const = fucntion() {}
を使用しましょう。
しかし、実際のところ関数の巻き上げを制限する理由ってあるんでしょうか・・・
バグの温床!というのはわからんでもないけど、実務経験がなく実感はないんですよね。
var
に比べれば好みの問題に収まってる話のような気はしてます。
(個人的には、アローが好きなので関数式派閥です。)
さて、次は何を書こうかしら・・・