関数(Function)

[up] [prev] [next]

目次

関数

function func(arg1, arg2, ...) { ... }

関数を定義します。関数とは、よく使用する処理を サブルーチン として定義するものです。例えば、時:分:秒を秒数に変換する関数を定義するには次のようにします。

JavaScript
function toSeconds(hour, min, sec) {
  var answer = hour * 3600 + min * 60 + sec;
  return(answer);
}

この関数は次のようにして呼び出すことができます。

JavaScript
sec1 = toSeconds(12, 34, 56);     // 12時間34分56秒 => 45296秒
sec2 = toSeconds(23, 59, 59);     // 23時間59分59秒 => 86399秒

関数を次のような形式で定義することもできます。

JavaScript
var toSeconds = function(hour, min, sec) {
  var answer = hour * 3600 + min * 60 + sec;
  return(answer);
}

function は、関数(処理)を定義するだけではなく、クラスを定義する目的でも使用されます。詳細は「クラスを定義する」を参照してください。

引数と戻り値

引数と戻り値

下記の例における hour, min, sec などのように、関数に渡す値を 引数、answer の値のように関数から戻される値を 戻り値 と呼びます。

JavaScript
function toSeconds(hour, min, sec) {
  var answer = hour * 3600 + min * 60 + sec;
  return(answer);
}
デフォルト引数

ES6(ES2015) からは、引数を省略した場合のデフォルト値を指定できるようになりました。下記の例では min や sec 引数を省略した場合、それぞれ 0分、0秒とみなされます。

JavaScript
function toSeconds(hour, min = 0, sec = 0) {
  var answer = hour * 3600 + min * 60 + sec;
  return(answer);
}
var sec = toSeconds(2);   // => 7200
可変長引数(...args)

ES6(ES2015) ではまた、可変長引数を扱うことが可能となりました。下記の例では、a, b, c は第1, 第2, 第3引数を、args は残りの引数の配列を受け取ります。

JavaScript
function func(a, b, c, ...args) {
  args.forEach((n) => {
    console.log(n);          // => 4, 5, 6
  });
}
func(1, 2, 3, 4, 5, 6);
末尾のカンマ

ES2017(ES8) では、関数定義や関数呼び出しの引数の最後にカンマ(,)を記述することが許容されました。

JavaScript
function func(
  theFirstArgument,
  theSecondArgument,
  theThirdArgument,
) {
 ...
}
ret = func(a, b, c,);

グローバル変数とローカル変数

変数は通常 グローバル変数(プログラム全体で有効な値)として扱われますが、arg1, arg2, ... 部分に指定した変数や、関数内で varlet で定義した変数は ローカル変数(関数内部でのみ有効な値)として扱われます。グローバル変数とローカル変数は、名前が同じでも別の変数として扱われます。

下記の例では、グローバル変数 xx と、ローカル変数 xx は名前は同じでも別の変数として扱われます。

JavaScript
xx = 5;               // グローバル変数 xx に 5 を代入
yy = 5;               // グローバル変数 yy に 5 を代入

func();               // 関数 func() を呼び出す

alert("xx = " + xx);  // グローバル変数 xx を表示(5 が表示される)
alert("yy = " + yy);  // グローバル変数 yy を表示(8 が表示される)

function func() {
   var xx = 8;        // ローカル変数 xx に 8 を代入
   yy = 8;            // グローバル変数 yy に 8 を代入
}

関数オブジェクト

func = new Function(arg1, arg2, ..., statements)

関数オブジェクトを作成します。下記のコードは上記のfunctionによる宣言と同等です。この方法はあまり利用されることはありません。

JavaScript
add = new Function("x", "y", "return(x+y)");
func.arity [廃止]
func.length

関数が要求する引数の個数を返します。arity は廃止されました。代わりに length を使用します。

JavaScript
function goukei(a, b, c) {
  return(a + b + c);
}
console.log(goukei.length);             // => 3
func.arguments

arguments は引数の配列を返します。個数不定の引数を受け取る際に便利です。アロー関数内では使用できません。今では arguments よりも 可変長引数(...args) を使用する方がよさそうです。

JavaScript
function goukei() {
  var ans = 0;
  for (var i = 0; i < arguments.length; i++) {
    ans += arguments[i];
  }
  return(ans);
}
sum = goukei(1, 2, 3, 4, 5);
this

this は、関数が実行されるターゲットのオブジェクトを参照します。例えば、ボタン要素のイベントハンドラの場合、this はボタン要素を示します。

HTML
<input type="button" onclick="console.log(this)" value="OK">
func.caller

この関数を呼び出した関数。将来の JavaScript のバージョンでは削除される予定らしいので使用しない方が無難です。

JavaScript
function func1(x, y) {
  func2();
}
function func2() {
  alert(func2.caller.arguments.caller);
}
func.prototype.newName

prototype

func.call(this, arg, ...)
func.apply(this, args)

JavaScript 1.3 で追加されたメソッドで、クラスの継承を実現します。詳細は「クラスを継承する」を参照してください。

func.bind(thisArg, arg1, arg2, ...)

this に thisArg を割り当て、引数 arg1, arg2, ... で呼び出される関数を生成します。

JavaScript
// グローバルオブジェクトのname属性
this.name = "Tanaka";

// moduleオブジェクトのname属性
var module = {
  name: "Yamada",
  getName: function() { return this.name; }
};

// moduleオブジェクトのname属性が参照される
console.log(module.getName());                 // "Yamada"

// グローバルコンテキストのため、thisはグローバルオブジェクトとなる
var retrieveName = module.getName;
console.log(retrieveName());                   // "Tanaka"

// thisにmoduleを割り当てた状態で retrieveName() を呼び出す
var boundGetName = retrieveName.bind(module);
console.log(boundGetName());                   // "Yamada"
func.toString()

関数定義を文字列に変換します。ES2019(ES10) では、関数内のコメントや空白も文字列化されるようになりました。

JavaScript
function add(x, y) {
    /* 加算 */
    return x + y;
}
console.log(add.toString());    // => function(x, y) { /* 加算 */ return x + y; }

コールバック関数

関数を、関数の引数として渡すことができます。時間が経過したり、処理が完了したりした際に、引数で登録した関数が呼び出されます。これを コールバック関数 と呼びます。下記の例は、3秒後にコールバック関数が呼ばれてメッセージを書き出す例です。

JavaScript
setTimeout(function() {
    console.log("Callback function called!!");
}, 3000);

再帰関数

関数の中から自分自身の関数を再帰的に呼び出す関数を 再帰関数(recursive function) と呼びます。下記は、n の階乗を求める再帰関数の例です。

JavaScript
function factorial(n) {
  if (n <= 1) {
    return 1;
  }
  return (n * factorial(n - 1));
}
console.log(factorial(5));            // => 120

即時関数

関数を宣言する際に関数の呼び出しも同時に行うものを 即時関数(IIFE: Immediately Invoked Function Expression) と呼びます。主に、グローバルスコープに初期化コードを記述する際に、使用する変数がグローバル変数となってしまい、グローバルスコープを汚染してしまうのを防ぐ目的で使用されます。

JavaScript
(function() {
  // 処理...
})();

括弧の位置をすこし変えて下記の様に書くことも多いようです。

JavaScript
(function() {
  // 処理...
}());

アロー関数(=>)

ES6(ES2015) では、function の代わりに => を記述するアロー関数がサポートされました。Chrome 45, Firefox 22, Edge 12, Opera 32, Safari 10 以降で使用できます。Internet Explorer では使用できません。下記は同じ意味になります。

ES5
var func = function(arg1, arg2) { console.log(arg1, arg2); }
ES6
var func = (arg1, arg2) => { console.log(arg1, arg2); }

下記の様な書き方ができます。

ES6
// 一般的な書き方
(arg1, arg2) => { return arg1 + arg2; }

// { } を省略すると return 文とみなされる
(arg1, arg2) => arg1 + arg2

// { } 省略でオブジェクトを返却する場合は () でくくる
(arg1, arg2) => ({"x": arg1, "y": arg2})

// 引数が1個の場合は ( ) を省略可能
arg1 => { return arg1 * 2; }

// 引数が0個の場合は ( ) が必要
() => { return 10; }

// 可変引数をサポート
(x, y, z, ...rest) => { ... }

// デフォルト引数をサポート
(file, mode = "r") => { ... }

function と => で this の扱いが異なります。function の場合は関数が呼ばれる対象のオブジェクトとなるのに対し、=> の場合は関数を呼び出す側の this となります。

ES6
function MyClass() {
  window.setTimeout(function() { console.log(this) }, 1000); // Window オブジェクト
  window.setTimeout(() => { console.log(this) }, 1000);      // MyClass オブジェクト
}
new MyClass();

arguments の扱いも異なります。function の場合は関数の引数を示しますが、=> の場合は関数を呼び出す側の引数を示します。

ES6
function func(a, b) {
  var func1 = function(a, b) { console.log(arguments); }
  func1(1, 2);    // [1, 2]
  var func2 = (a, b) => { console.log(arguments); }
  func2(3, 4);    // [5, 6]
}
func(5, 6);

[up] [prev] [next]
Copyright (C) 1996-2019 杜甫々
改訂版初版:2001年5月20日、最終更新:2019年11月17日
http://www.tohoho-web.com/js/function.htm