7cc@はてなブログ

JavaScriptとかとか

関数式と関数宣言の優先順位 JavaScript

基礎事項

2つの違いについての説明は最低限のみします

構文

関数宣言(declaration) function x() {}
関数式(expression) var x = function(){}

本当は違うけれど・・・詳細はFunction コンストラクタか関数宣言か関数式か

"関数宣言は同時にその関数名と同じ名前の変数を作成" する

;(function(){
  "use strict"
  a = 1 // var で変数宣言をしていないがエラーにならない。
  function a(){} // 関数宣言をあとで宣言しても、このスコープではaが変数となるから
})()


;(function(){
  "use strict"
  a = 1 // assignment to undeclared variable こちらでは a が変数ではないのでエラー
})()

優先順位 (本題)

  • 関数宣言は最後のものが実行される
  • 関数式は関数宣言によっては再代入されない
  • 同名の関数式と関数宣言がある場合
    • 関数式の前までは関数宣言が実行される
    • 関数式の後では関数式が実行される

単純に言うとのほうが優先順位が高い

function fn() {
  console.log(1);
}


fn() // 3 最後の関数宣言が実行

fn = function() {
  console.log(2);
}

fn(); // 2

function fn() {
  console.log(3);
}

fn(); // 2 関数宣言は再代入はされない。式が実行

fn = function() {
  console.log(4);
}

fn(); // 4 関数式は再代入される

さらにこうなる

function a(){
  alert(1)
  a = "a"
}

a() // alert
a() // a is not a function

最初はalertが実行されるが、内部で文字列が代入されるのでエラー