console で hoisting されない
- カテゴリ:
- JavaScript
- コメント数:
- Comments: 0
◆ async 関数ラップの結果
◆ Chrome は宣言なし代入になるので代入式より前じゃ使えない
◆ Firefox は最後が関数文だと return の都合か消される
◆ 最後じゃなければ hoisting されるけどローカルスコープなので次の実行では使えない
◆ Chrome は宣言なし代入になるので代入式より前じゃ使えない
◆ Firefox は最後が関数文だと return の都合か消される
◆ 最後じゃなければ hoisting されるけどローカルスコープなので次の実行では使えない
await fn()
function fn() {
return new Promise(a => a(1))
}
これを console に貼り付けて実行するとエラーになります
fn が定義されていないというものです
Chrome でも Firefox でも起きます
fn は function 文なので hoisting (巻き上げ) があるので一見大丈夫そうに見えます
ですがトップレベル await サポートのために内部で変換が行われてるので hoisting が起きません
Chrome の場合はこう変換されています
(async () => {await fn()
fn=function fn() {
return new Promise(a => a(1))
}
})()
function 文じゃないので定義の前では使えません
Firefox の場合はこう変換されています
(async () => {
await fn();
return;
})();
fn の定義がありません
なぜか消されるようです
しかし function 文の後になにかの式があれば残ります
debugger;await fn()
function fn() {
return new Promise(a => a(1))
}
100
このコードだと下のように変換されます
(async () => {
debugger;
await fn();
function fn() {
return new Promise(a => a(1));
}
return 100;
})();
消された方では 最後に return をつけようとしたけどそれが式じゃなくて function 文だったのでスキップしたというところでしょうか
一応ほかも試したところ if や try-catch など 式以外が最後ならどれも消えてました
if が連続するなど式以外が最後に続いていると最後だけが消えていました
さすがにこの完成度でトップレベル await を組み込んでしまうのはどうかと思います
また 最後が function 文でなければ hoisting されるので実行はできるものの 暗黙的に作られた async 関数のローカルスコープになるので 次に console で入力するコードでは fn は未定義となり使えません
console でのトップレベル await は罠が多いですね
ちなみに実行は Chrome 77 / Firefox 69 で行ってます