LoginSignup
2
7

More than 5 years have passed since last update.

JavaScript文法(6) 関数の応用2

Last updated at Posted at 2016-09-05

この記事の内容

  • 関数の引数に関数を指定する方法
  • コールバック関数について

目次

(1) 学習環境の構築と基本的な書き方
(2) 変数とデータ型
(3) 演算子および配列
(4) 制御構文と関数
(5) 関数の応用1
(6) 関数の応用2 <-- この記事の内容
(7) オブジェクトの基礎
(8) JavaScriptのオブジェクト指向プログラミング1 概要
(9) JavaScriptのオブジェクト指向プログラミング2 オブジェクトの作り方と継承
(10) JavaScriptのオブジェクト指向プログラミング3 多態性
(11) JavaScriptのオブジェクト指向プログラミング4 カプセル化
(12) ES6の新機能について

関数の引数に関数を指定する

前回の続き。関数の引数に関数を指定して、関数の中で「引数として渡した関数」を実行してもらうことがJavaScriptでは可能である。

bs06_01.js
// 引数funcに渡された関数を実行する
var sumFunc = function(a, b, func) {
  return func(a) + func(b);
};

// 13 が表示される(3 * 3 + 2 * 2の計算結果)
console.log(sumFunc(3, 2, function(x) {
  return x * x;
}));

sumFunc関数では、3番目の引数で関数を受け取り、その関数を実行する。引数として受け渡す関数の処理内容は、引数の数値を2乗する計算である。func(a) + func(b)とあるように、引数aと引数bに渡された数値で、その計算処理(2乗する計算)を行い、それぞれの計算結果を加算してreturnするのがsumFunc関数である。このように、関数の引数に関数を渡すことができる。

コールバック関数

関数の引数に関数を指定できるJavaScriptの仕様の代表的な利用例として、コールバック関数がある。関数としてひとまとめにした処理の最後に実行したい関数を、引数として指定する記述方法である。

bs06_02.js
// 面積を求めるcalcSquare関数
var calcSquare = function(a, b, callback) {
  console.log("処理開始");
  console.log("面積は " + (a * b));
  callback();            // コールバック関数を実行
};

// コールバック関数の内容は、処理終了 と表示するだけの処理
calcSquare(10, 5, function() {
  console.log("処理終了");
});
bs07_02.jsの実行結果
処理開始
面積は 50
処理終了

このように記述することで、処理の最後に、引数で渡された処理を実行することができる。
コールバック関数の利点としては、1つに、calcSquare関数の再利用が可能である点が挙げられる。実際、JavaScript製のライブラリでは、コールバック関数が指定できるように実装されているものが多数ある。

コールバック関数と非同期処理

もう1つ、コールバック関数は、Ajax通信などの非同期処理で非常に役に立つ。ここでは、非同期処理を実現する命令の中でも手軽な setTimeout 関数を利用して、話を進める。

まず、このような内容を記述して実行してみる。

bs06_03.js
console.log("処理開始");

setTimeout(function() {
  console.log("処理実行");
}, 3000);

console.log("処理終了");

setTimeout 関数は、引数として指定した関数(ひとまとまりの処理)を、指定したミリ秒後に実行する。ここでは、

setTimeout(function() {
  console.log("処理実行");
}, 3000);

このように記述しているので、「処理開始」と表示された3000ミリ秒(3秒後)に「処理実行」を表示することになる。しかし、実際の処理結果は、以下のようになる。

b06_03.jsの実行結果
処理開始
処理終了
処理実行

setTimeout の下にある「処理終了」を表示する命令が先に実行されてしまうのである。これは、setTimout で指定した命令が非同期処理として実行されるため、setTimeout の実行完了を待たずして、setTimeout の下に続く命令が順次実行されていくことになる。

非同期処理が完了したタイミングで何らかの処理を実行させたい場合は、コールバック関数を利用して記述する。

bs07_04.js
// 非同期処理の定義
var execTimeOutFunc = function(callback) {
  setTimeout(function() {
    console.log("非同期処理実行");
    callback();
  }, 3000);
};

// ここから処理開始
console.log("処理開始");

execTimeOutFunc(function() {
  console.log("非同期処理完了");
});

console.log("処理終了");
b06_04.jsの実行結果
処理開始
処理終了
非同期処理実行
非同期処理完了

このように記述することで、「非同期処理完了」の表示は、確実に「非同期処理実行」の後で表示される。

次回予告

オブジェクトの基礎

2
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
7