【JavaScript】関数宣言と関数式(アロー関数:「ES6」(2015年から)でJavaScriptの新しい文法として追加された機能)

JavaScript

関数宣言(function文)

function func1(n) {
  return "これはfunc1です。値は" + n;
}
var result = func1(1);
var name = func1.name;
alert(name + ": " + result);
// 出力⇒func1: これはfunc1です。値は1

JavaScriptでは、関数もオブジェクトである(Functionオブジェクト)。オブジェクトであるから、プロパティやメソッドを持っている。上のコードでは、関数の名前を表すnameプロパティを使っている。

関数式(function演算子)

関数式(function演算子)を使うコード

// 無名関数
{
  var func2 = function (n) {
    return "これはfunc2です。値は" + n;
  }
  var result = func2(2);
  var name = func2.name;
  if (name === "")
    name = "(空文字)";
  alert(name + ": " + result);
  // 出力⇒(空文字): これはfunc2です。値は2
}

// 名前付き関数
{
  var func3 = function function3 (n) {
    return "これはfunc3です。値は" + n;
  }
  var result = func3(3);
  var name = func3.name;
  alert(name + ": " + result);
  // 出力⇒function3: これはfunc3です。値は3
}

関数式では、関数名を省略できる。関数式はそのままでは呼び出せず、このコードのように変数に代入するなどしてから呼び出す。そのため、関数式に関数名を指定するのはあまり意味がない。関数名が必要だと思えるのは、再帰関数を書くときくらいではないだろうか(無名関数でも再帰は書けるが、少しだけ分かりにくい)。
関数名を省略した場合、生成されたFunctionオブジェクトのnameプロパティは空文字になる。

アロー関数式を使うコード

// ブロック文体(block body)…値を返すにはreturn文が必要
{
  var func4 = (n) => {
    return "これはfunc4です。値は" + n;
  };
  var result = func4(4);
  var name = func4.name;
  alert(name + ": " + result);
  // 出力⇒func4: これはfunc4です。値は4
}

// 簡潔文体(concise body)…暗黙的に値が返される
{
  var func5 = n => "これはfunc5です。値は" + n;
  var result = func5(5);
  var name = func5.name;
  alert(name + ": " + result);
  // 出力⇒func5: これはfunc5です。値は5
}

ECMAScript 2015(第6版)からは、上記のコードに示すようなアロー関数式も追加された。

アロー関数式のサンプル :アロー関数式

関数宣言と関数式の違い

関数宣言と関数式の違いは、端的に言うと、Functionオブジェクトの生成されるタイミングが違う。

関数宣言は、宣言を含むスコープが実行されるまでにFunctionオブジェクトが生成される。対して関数式は、その式が実行されるときにFunctionオブジェクトが生成される。

そのため、Functionオブジェクトを生成するのに時間がかかる巨大で複雑な関数の場合には、関数宣言と関数式でパフォーマンスに違いが出てくるはずである(どちらがよいとは一概にはいえない)。通常は、書きやすい方を使えばよい。

コーディングの実用面では、関数宣言はそれより手前でも呼び出せるが、関数式では文法エラーになる。

// 関数宣言は、その手前でも呼び出せる
{
  var result = func1(1);
  var name = func1.name;
  alert(name + ": " + result);
  // 出力⇒func1: これはfunc1です。値は1

  function func1(n) {
    return "これはfunc1です。値は" + n;
  }
}

// 関数式は、その手前では呼び出せない
{
  var result_NG = func2(2); // × 文法エラー

  var func2 = function (n) {
    return "これはfunc2です。値は" + n;
  }
}
関数宣言: 
func1関数のFunctionオブジェクトは、遅くともそのスコープの実行が始まるまでに生成される。
そのため、関数宣言の手前でも呼び出せる。
関数式: 
変数func2が参照するFunctionオブジェクトが生成されるのは、「var func2 =……」の行が
実行されたとき。従って、それよりも前ではFunctionオブジェクトが存在しない
(strictモードでは変数func2も存在しない)ので、呼び出せない。

 

タイトルとURLをコピーしました