JavaScriptの関数と「書く場所・呼ぶ順番」の基本
はじめてのコードって、ちょっとした「置く場所の違い」で動いたり動かなかったりしますよね。関数は特にその影響を受けます。ここでは、初心者でもつまずかないように、動くパターン・動かないパターンを例題でかみ砕いて説明します。
なぜ「書く場所・呼ぶ順番」が大事なのか
- 関数宣言の巻き上げ(hoisting)がある:
function 名前() { ... }という「関数宣言」は、ファイルの上に持ち上げられて認識されます。だから前で呼んでも動きます。 - 関数式は巻き上げられない:
const f = function() { ... }など「変数に入れた関数(関数式)」は、代入が実行されるまで使えません。前で呼ぶとエラーになります。 - スクリプトの分割で読み込み順が変わる:
<script>タグが複数あると、上から順に読み込まれるので、後のタグにある関数は前では使えないことがあります。 - スコープ(見える範囲)の違い: 関数の中で作った関数や変数は、その外からは見えません。
動くパターンと動かないパターンの例
関数宣言は「前で呼んでも」動く
<script>
// まだ下に定義があるけど、呼べる
greet(); // => "こんにちは!"
function greet() {
console.log("こんにちは!");
}
</script>
JavaScript- ポイント: 関数宣言は巻き上げの対象。定義より前でも呼べる。
関数式は「定義後に」しか呼べない
<script>
// ここで呼ぶとエラー(f はまだ undefined)
// f(); // ReferenceError になるのでコメントアウト
const f = function () {
console.log("関数式です");
};
// 代入が実行された「後」ならOK
f(); // => "関数式です"
</script>
JavaScript- ポイント: 関数式やアロー関数(
const f = () => {})は「代入が終わるまで」使えない。
<script>タグが複数ある場合の落とし穴
<!-- 上のスクリプト -->
<script>
// ここで sayHi を呼ぶとエラー
// sayHi(); // 未定義(この時点ではまだ読み込まれていない)
</script>
<!-- 下のスクリプト -->
<script>
function sayHi() {
console.log("やっほー");
}
</script>
JavaScript- ポイント: ブラウザは上から順に読み込む。上の
<script>では、下の<script>の関数はまだ存在しない。
関数の中で定義した関数は「外から呼べない」
<script>
function outer() {
function inner() {
console.log("内側だけで使える関数");
}
inner(); // ここでは呼べる
}
outer(); // => "内側だけで使える関数"
// inner(); // これはエラー(外からは見えない)
</script>
JavaScript- ポイント:
innerはouterの中だけの「ローカル」。外からはアクセス不可。
つまずかないための実践ルール
- 基本ルール: 先に関数を書いて、あとで呼ぶ。迷ったらこの順番。
- 関数式を使うとき: 必ず「定義の後」で呼ぶ。
const f = () => {}は呼び出し位置に注意。 - HTMLで分割するとき: 使いたい関数は「上の
<script>に定義」、呼ぶのは「下の<script>」。 - 見える範囲(スコープ): 外から呼びたい関数は「外で宣言」。内だけなら関数の中で宣言。
手を動かして覚えるミニ演習
- 演習1(できるはず): 関数宣言を下に置いて、上で呼んでみる。
<script>
hello(); // "Hello!" を期待
function hello() { console.log("Hello!"); }
</script>
JavaScript確認ポイント: エラーが出ないこと。巻き上げが効いている。
- 演習2(わざと失敗してみる): 関数式を下に置いて、上で呼ぶ。
<script>
// try(); // コメントを外すとエラーになるはず
const tryFn = function() { console.log("Try!"); };
</script>
JavaScript確認ポイント: なぜエラーかを説明できる(代入前で未定義)。
- 演習3(スクリプト分割): 2つの
<script>を用意して、上で呼び出し、下で定義してみる。エラーになったら順番を入れ替える。 - 演習4(スコープ): 関数の中で作った関数を外から呼んでみて、エラーを確認。必要なら外に出して「使える範囲」を広げる。
迷ったときのチェックリスト
- 定義は呼び出しより前か?(関数式なら必須)
- 同じ
<script>の中で完結しているか?(分割しているなら順番に注意) - 外から呼びたい関数を内側に閉じ込めていないか?(スコープの見直し)
- 名前のタイポがないか?(
sayHiとsayHIなど)
