関数を定義します。関数とは、よく使用する処理を サブルーチン として定義するものです。例えば、時:分:秒を秒数に変換する関数を定義するには次のようにします。
function toSeconds(hour, min, sec) { var answer = hour * 3600 + min * 60 + sec; return(answer); }
この関数は次のようにして呼び出すことができます。
sec1 = toSeconds(12, 34, 56); // 12時間34分56秒 => 45296秒 sec2 = toSeconds(23, 59, 59); // 23時間59分59秒 => 86399秒
関数を次のような形式で定義することもできます。
var toSeconds = function(hour, min, sec) { var answer = hour * 3600 + min * 60 + sec; return(answer); }
function は、関数(処理)を定義するだけではなく、クラスを定義する目的でも使用されます。詳細は「クラスを定義する」を参照してください。
下記の例における hour, min, sec などのように、関数に渡す値を 引数、answer の値のように関数から戻される値を 戻り値 と呼びます。
function toSeconds(hour, min, sec) { var answer = hour * 3600 + min * 60 + sec; return(answer); }
ES6(ES2015) からは、引数を省略した場合のデフォルト値を指定できるようになりました。下記の例では min や sec 引数を省略した場合、それぞれ 0分、0秒とみなされます。
function toSeconds(hour, min = 0, sec = 0) {
var answer = hour * 3600 + min * 60 + sec;
return(answer);
}
var sec = toSeconds(2); // => 7200
ES6(ES2015) ではまた、可変長引数を扱うことが可能となりました。下記の例では、a, b, c は第1, 第2, 第3引数を、args は残りの引数の配列を受け取ります。
function func(a, b, c, ...args) {
args.forEach((n) => {
console.log(n); // => 4, 5, 6
});
}
func(1, 2, 3, 4, 5, 6);
ES2017(ES8) では、関数定義や関数呼び出しの引数の最後にカンマ(,)を記述することが許容されました。
function func( theFirstArgument, theSecondArgument, theThirdArgument, ) { ... } ret = func(a, b, c,);
変数は通常 グローバル変数(プログラム全体で有効な値)として扱われますが、arg1, arg2, ... 部分に指定した変数や、関数内で var や let で定義した変数は ローカル変数(関数内部でのみ有効な値)として扱われます。グローバル変数とローカル変数は、名前が同じでも別の変数として扱われます。
下記の例では、グローバル変数 xx と、ローカル変数 xx は名前は同じでも別の変数として扱われます。
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 を代入 }
関数オブジェクトを作成します。下記のコードは上記のfunctionによる宣言と同等です。この方法はあまり利用されることはありません。
add = new Function("x", "y", "return(x+y)");
関数が要求する引数の個数を返します。arity は廃止されました。代わりに length を使用します。
function goukei(a, b, c) {
return(a + b + c);
}
console.log(goukei.length); // => 3
arguments は引数の配列を返します。個数不定の引数を受け取る際に便利です。アロー関数内では使用できません。今では arguments
よりも 可変長引数(...args) を使用する方がよさそうです。
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 はボタン要素を示します。
<input type="button" onclick="console.log(this)" value="OK">
この関数を呼び出した関数。将来の JavaScript のバージョンでは削除される予定らしいので使用しない方が無難です。
function func1(x, y) { func2(); } function func2() { alert(func2.caller.arguments.caller); }
JavaScript 1.3 で追加されたメソッドで、クラスの継承を実現します。詳細は「クラスを継承する」を参照してください。
this に thisArg を割り当て、引数 arg1, arg2, ... で呼び出される関数を生成します。
// グローバルオブジェクトの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"
関数定義を文字列に変換します。ES2019(ES10) では、関数内のコメントや空白も文字列化されるようになりました。
function add(x, y) {
/* 加算 */
return x + y;
}
console.log(add.toString()); // => function(x, y) { /* 加算 */ return x + y; }
関数を、関数の引数として渡すことができます。時間が経過したり、処理が完了したりした際に、引数で登録した関数が呼び出されます。これを コールバック関数 と呼びます。下記の例は、3秒後にコールバック関数が呼ばれてメッセージを書き出す例です。
setTimeout(function() { console.log("Callback function called!!"); }, 3000);
関数の中から自分自身の関数を再帰的に呼び出す関数を 再帰関数(recursive function) と呼びます。下記は、n の階乗を求める再帰関数の例です。
function factorial(n) {
if (n <= 1) {
return 1;
}
return (n * factorial(n - 1));
}
console.log(factorial(5)); // => 120
関数を宣言する際に関数の呼び出しも同時に行うものを 即時関数(IIFE: Immediately Invoked Function Expression) と呼びます。主に、グローバルスコープに初期化コードを記述する際に、使用する変数がグローバル変数となってしまい、グローバルスコープを汚染してしまうのを防ぐ目的で使用されます。
(function() {
// 処理...
})();
括弧の位置をすこし変えて下記の様に書くことも多いようです。
(function() {
// 処理...
}());
ES6(ES2015) では、function の代わりに => を記述するアロー関数がサポートされました。Chrome 45, Firefox 22, Edge 12, Opera 32, Safari 10 以降で使用できます。Internet Explorer では使用できません。下記は同じ意味になります。
var func = function(arg1, arg2) { console.log(arg1, arg2); }
var func = (arg1, arg2) => { console.log(arg1, arg2); }
下記の様な書き方ができます。
// 一般的な書き方 (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 となります。
function MyClass() { window.setTimeout(function() { console.log(this) }, 1000); // Window オブジェクト window.setTimeout(() => { console.log(this) }, 1000); // MyClass オブジェクト } new MyClass();
arguments の扱いも異なります。function の場合は関数の引数を示しますが、=> の場合は関数を呼び出す側の引数を示します。
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);