関数
1.function命令
通常のやり方。解析時に登録され、宣言より上からでも呼び出せる
console.log(getPlus(8)); function getPlus(x) { return x + 10; }
2.Functionオブジェクト
文字列として定義できる。ただ必要ない限り使わない。
var getTri = new Function("base", "height", "return base * height / 2"); console.log(getTri(2, 6));
3.関数リテラル
無名関数を定義して変数に入れる。function命令とは異なり、実行時に評価される。
let getMinus = function (x) { return x * -1; };
4.アロー関数
ES6で対応、関数リテラルをシンプルにかける
(要注意)使えない場所もある、コンストラクタ、メソッド、yieldなど
thisの固定ができる
let fnArrow1 = (x, y) => { return x * y * 2; }; console.log(fnArrow1(1, 2)); // 一行の場合{}とreturnを省略可能、引数が1個の場合()を省略可能 let fnArrow2 = (x) => x + 10; // オブジェクトリテラルを返す場合()で囲む let fnArrow3 = (x) => ({ val: x });
デフォルト引数
ES6でない場合は出来ないので自前でやる。
calc(99); function calc(x, y, z) { if (y === undefined) y = 0; console.log(x, y, z); } // (ES6)ならデフォルト値の指定が可能。undefined以外 calc2(88); function calc2(x = 0, y = 0, z = 0) { console.log(x, y, z); } //(ES6)分割代入でデフォルト値を指定できる defobj({ price: 0 }); function defobj({ title = "unknown", price = 0 }) { console.log(title, price); }
引数の数が間違っててもエラーにならない
足りなくても、多すぎてもエラーにならない恐ろしい仕様。
例外を発生させるオブジェクトを作ってデフォルト値に設定すれば機能するが、なんかブサイク。
function calc3(x = required()) {} function required() { throw new Error("a requied argument is missing!"); }
可変長引数
ES6なら出来るが、そうでないなら関数内でargumentsオブジェクトというのが使えるためそこから頑張って取り出す。
multiarg("john", 1, 9, 4); function multiarg(name, _args) { // _argsは使わないのでなくてもいい。可読性のため。 // 2つめ以降の引数はargumentsから取得 args = []; for (let i = 1; i < arguments.length; i++) { args.push(arguments[i]); } console.log(args); }
(ES6)可変長引数、Arrayオブジェクトとして受け取れる
calc4(11, 22, 33); function calc4(...nums) { for (num of nums) { console.log(num); } }
実引数のアンパック
(ES6)なら...を前につけると配列を引数として展開できる。アンパック
console.log(...["A", "B", "C"]);