DESIGNMAP

  1. TOP
  2. 公開講座
  3. ゼロから始めるJavaScript入門
  4. オブジェクトとしての関数 ー ゼロから始めるJavaScript入門(ECMAScript 2015)【Vol.15】

オブジェクトとしての関数 ー ゼロから始めるJavaScript入門(ECMAScript 2015)【Vol.15】

関数 ー ゼロから始めるJavaScript入門(ECMAScript 2015)【Vol.9】」で関数の定義を学び、「コンストラクタ、オブジェクトを参照する変数 ー ゼロから始めるJavaScript入門(ECMAScript 2015)【Vol.13】」でコンストラクタとしての関数を学びました。

JavaScriptの関数はオブジェクトとしての側面をもっています。
変数に代入したり、別な関数の引数に実引数として渡したり、関数の戻り値として返したり、オブジェクトのプロパティに代入したりなど、より柔軟な関数の使い方ができます。

今回はオブジェクトとしての関数を学びます。

オブジェクト ー ゼロから始めるJavaScript入門(ECMAScript 2015)【Vol.12】」の内容が説明の前提となります。

関数はオブジェクトです。
なのでnew演算子とコンストラクタ関数からオブジェクトとしての関数をつくることができます。

実際には以下のようなコードを書くことはないですが、仕様上、動作します。

var add = new Function("num1", "num2", "return num1 + num2");
  console.log(add(3, 5));

実行結果:

8

Functionはコンストラクタ関数です。new演算子とともなって呼び出すことで、オブジェクトとしての関数を生成しています。add変数はメモリにできた関数オブジェクトを参照しています。

関数式

上記のコードの代わりに下記のコードが代わりに使われます。
実際に書いていきましょう。

Atomで新規ファイルをつくり「文字列型 ー ゼロから始めるJavaScript入門(ECMAScript 2015)【Vol.2】」で作った「js-study」フォルダ内に、「func-object1.html」というファイル名で保存します。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
  <script>
  var add = function(num1, num2){
    return num1 + num2;
  };

  console.log(add(3, 5));
  </script>
  </body>
</html>

Google Chromeで「func-object1.html」を開き、JavaScriptコンソールを開きます。8が出力されていれば成功です。

8
  var add = function(num1, num2) {
    return num1 + num2;
  };

の右辺は関数式とよばれています。これでメモリに関数オブジェクトがつくられ、add変数は関数オブジェクトを参照します。名前のない関数オブジェクトをつくり変数に代入しています。

関数定義と関数式は関数リテラル

関数 ー ゼロから始めるJavaScript入門(ECMAScript 2015)【Vol.9】」で

function add(num1, num2) {
        return num1 + num2;
}

var sum = add(5, 6);

という書き方を学びました。こちらは関数宣言と呼ばれる書き方です。

どちらも関数リテラルと呼ばれます。new Functionで関数オブジェクトをつくることはほぼなく、この2つの関数リテラルで関数オブジェクトはつくられます。

リテラルを使うとコンストラクタ関数からオブジェクトをつくる手間がなく、ダイレクトにオブジェクトがつくれます。

関数式の場合、関数名を省略することができます。関数宣言の場合は、関数名は必要です。
関数式の場合、変数や配列に代入したり、オブジェクトのプロパティに代入することができます。

関数定義は巻き上げされる、関数式は巻き上げされない

関数式と関数定義の大きな違いに巻き上げがあります。
以下のコードが関数宣言より前に、関数を呼び出していますがエラーにはならず11が出力されます。

var sum = add(5, 6);
console.log(sum);

function add(num1, num2) {
        return num1 + num2;
}

実行結果:

11

これは関数定義は、コードの頭に巻き上げされるからです。

ところが関数式で同じようなコードを書くとエラーになります。

console.log(add(3, 5));

var add = function(num1, num2){
   return num1 + num2;
};
Uncaught TypeError: add is not a function

addは関数ではないですよというエラーです。
関数式は巻き上げされません。
なので、下記のように関数式を書いて、変数に代入した後に呼び出す必要があります。

var add = function(num1, num2){
   return num1 + num2;
};
console.log(add(3, 5));

実行結果:

11

関数の引数に関数式を渡す

関数の引数に関数式を渡すことができます。
Atomで新規ファイルをつくり「js-study」フォルダ内に、「func-object2.html」というファイル名で保存します。
コードは<script>以前、</script>以降のコードは「func-object1.html」と同じなので掲載は省略しています。

以下のコードを書いて保存します。

  var func_a = function(func) {
    return func;
  }

  var add = func_a(function(num1, num2) {
    return num1 + num2;
  });

  console.log(add(3, 5));

実行すると、JavaScriptコンソールには8が出力されます。

8

func_a変数は関数オブジェクトを参照しています。
この関数は関数式を仮引数にとり、関数式を戻り値として返しています。

あとは下記のようにfunc_a変数を関数のように呼び出して、実引数に関数式を渡しています。

var add = func_a(function(num1, num2) {
    return num1 + num2;
});

この引数に関数式を渡すパターンはJavaScriptでは多用されます。

プロパティの追加

関数はオブジェクトなので「オブジェクト ー ゼロから始めるJavaScript入門(ECMAScript 2015)【Vol.12】」の回で学んだように、プロパティを追加することができます。

func_test = function() {};

func_test.title = "タイトル";

console.log(func_test);
console.log(func_test.title);
function () {}
タイトル

ただし実際にこういうコードを書くことはないです。

オブジェクトのプロパティに関数式を代入する

オブジェクトのプロパティに関数式を代入することもできます。これも「オブジェクト ー ゼロから始めるJavaScript入門(ECMAScript 2015)【Vol.12】」の回で学習しています。

コードを再掲しておきます。

var book = {
  id: 1,
  title: "三四郎",
  price: 800,
  getTitle: function(){
    return this.title;
  }
};

console.log(book.getTitle());
三四郎

関数式が使われています。thisは、インスタンス化されたオブジェクト自身を指しています。

スポンサーリンク

関連記事

プロフィール

DESIGNMAP
ディレクター・Web制作者
ON VISITINGを制作・運営。
お問い合わせ