こういう記事があり
ブックマークレットに使えると考えて実験した結果を共有します。
{
function a() {
console.log("aaaaaaaaaaaaaaaaaaaa");
}
const b = () => {
console.log("bbbbbbbbbbbbbbbbbbbb");
};
a();/* aaaaaaaaaaaaaaaaaaaa */
b();/* bbbbbbbbbbbbbbbbbbbb */
}
a();/* aaaaaaaaaaaaaaaaaaaa */
b();/* ReferenceError: b is not defined */
以上のように、ブロック内で定義されたアロー関数は外では利用できないことがわかりました。
追記:2024-04-24
直前の部分について次のようなコメントをいただきました。
ブロック外で使用できないのは「ブロック内で定義したアロー関数」だからではなく、「ブロック内でブロックスコープであるconstを使って宣言した」からです。
なので、constではなくvarで宣言してしまうと、「ブロック内で定義したアロー関数」であってもブロック外でも使用できてしまいます。
その通りですね。内容について付け加えたいことはありません。
var
って何?って人のために解説すると、ES2015
以前には var
文というものがあり(今でも使えます)、人々は関数スコープまたはグローバルスコープに所属する変数を宣言していました。
プログラマがグローバル名前空間の汚染を避けたい場合は次章で言及している即時実行関数式を使っていたと伝えられています。
アロー関数は let
、const
と同じ ES2015
で導入されました。正直に言うと、アロー関数を「constではなくvarで宣言」するという発想はまったくなかったですね。
JavaScript
のスコープはグローバルスコープ、関数スコープ…というふうに別れています。この説明はブックマークレットの記事でやることではないので、別の記事に譲ります。
var
の動作は以下のサンプルコードの通りです。
今回初めて知ったのですが var var_f = () => {}
って動くんですね。そりゃ、動くんでしょうけど思いつきませんでした。
{
var var_str = "var_text";
let let_str = "let_text";
const const_str = "const_text";
let let_f = () => {
console.log("let_f");
};
var var_f = () => {
console.log("var_f");
};
console.log(var_str, let_str, const_str); // var_text let_text const_text
}
var_f(); // var_f
console.log(var_str); // var_text
let_f(); // ReferenceError: let_f is not defined
console.log(let_str); // ReferenceError: let_str is not defined
console.log(const_str); // ReferenceError: const_str is not defined
つまり、アロー関数や変数をブロック内に封じ込めるには
-
const
、let
で宣言する -
var
を使う際には、即時実行関数式でラップする
が必要になります。
何が嬉しいか?
ブックマークレットではグローバル名前空間を汚さないためにスクリプトを即時実行関数式でラップすることが推奨されています。
ブロックはブックマークレットでの即時実行関数式の代替として利用できます。
ブロックは単純にタイプ数が少ないのとカッコを数えやすいという利点があります。
逆に即時実行関数式には function
宣言された関数と var
宣言された変数、関数があってもはグローバル名前空間を汚さないという利点があります。