[JavaScript General] JavaScript における function 引数のあれこれ
初期値、可変長、名前付き、必須、関数。
[markdown]
分かる範囲で整理。
## Default Parameter
ES2015 から初期値の設定ができるようになった。
> * [ES6時代のJavaScript – クックパッド開発者ブログ](http://techlife.cookpad.com/entry/2015/02/02/094607)
“`javascript
function loop(func, count = 3) {
for (let i = 0; i < count; i++) {
func();
}
}
loop(function(){console.log('hello')}); // hello hello hello
``` > * [デフォルト引数 – JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions_and_function_scope/Default_parameters)
## Rest Parameter
可変長引数は arguments を利用して書く必要があった。
> * [arguments – JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions_and_function_scope/arguments)
>
> arguments はすべての関数内で利用可能なローカル変数です。arguments オブジェクトを使うことにより、関数内で関数の引数を参照できます。
ES2015 から、可変長引数を受け取る事ができる。
> * [ES6時代のJavaScript – クックパッド開発者ブログ](http://techlife.cookpad.com/entry/2015/02/02/094607)
numbers に `[1,2,3,4]` が入り、結果 10 となる.
“`javascript
function sum(…numbers) {
return numbers.reduce(function(a, b) { return a + b; });
}
console.log(sum(1, 2, 3, 4)); // 10
“`
いろいろあるよう。
> * [Destructuring and parameter handling in ECMAScript 6](http://www.2ality.com/2015/01/es6-destructuring.html)
### 引数の数をチェックする
`arguments.length` を利用していた。
“`javascript
function f(x, y) {
if (arguments.length > 2) { throw new Error(); }
var x = arguments[0];
var y = arguments[1];
“`
ES2015では、レストパラメータで受け取って、変数へ分割代入できる。
> * [11. Parameter handling](http://exploringjs.com/es6/ch_parameter-handling.html#_enforcing-a-maximum-arity)
“`javascript
function f(…args) {
if (args.length > 2) { throw new Error(); }
let [x, y] = args;
“`
## Named parameter
名前付きパラメータは、`args.path` といった形で扱っていた。
“`javascript
function showPanel(args) {
if (args.path === undefined) { throw {name: ‘ArgsMissing’, message: ‘Missing parameter’}; }
if (args.height === undefined) { args.height = 200; }
if (args.width === undefined) { args.width = 300; }
“`
ES2015 から関数引数の分割代入が可能になったので、このように書ける。
> * [function – Named parameters in javascript – Stack Overflow](http://stackoverflow.com/questions/11796093/named-parameters-in-javascript)
“`javascript
function showPanel2({path, height = 200, width = 300} = {}) {
if (path === undefined) { throw new Error(‘Missing parameter’); }
“`
See the Pen JavaScript ES2015 Named Parameters by DriftwoodJP (@DriftwoodJP) on CodePen.
## Required Parameter
受け取った Parameter が undefined かどうかをチェックする。
“`javascript
function getArea(r_width, o_height = 1) {
// Required params
if (r_width === undefined) {
throw { name: ‘ArgsMissing’, message: ‘幅が指定されていません。’}
}
return r_width * o_height;
}
try {
console.log(getArea(10, 5)); // 50
console.log(getArea(10)); // 10
console.log(getArea()); // error
} catch(e) {
console.log(e.message);
}
“`
基本的な考え方は変わらない模様。
ES2015 から、前述のディフォルト値を利用してこんな書き方ができる。
> * [11. Parameter handling](http://exploringjs.com/es6/ch_parameter-handling.html#sec_parameter-handling-style-tips)
See the Pen JavaScript ES2015 Required parameters by DriftwoodJP (@DriftwoodJP) on CodePen.
## Higher-order Functions, aka Callback Functions
関数を引数にとる、関数を戻り値にとる関数を「高階(こうかい)関数」と呼ぶ。
> * [連載:Ajax時代のJavaScriptプログラミング再入門:第2回 JavaScriptの関数をマスターしよう (3/4) – @IT](http://www.atmarkit.co.jp/ait/articles/0707/10/news124_3.html)
以下の場合、
– 関数 benchmark() は、引数として関数 proc を受け取る __高階関数__ となる。
– 呼び出し先の関数で呼び出される関数 proc を __コールバック関数__ と呼ぶ。
– 再利用の必要がないのでコールバック関数を __関数リテラル(匿名関数)__ の形式で受け渡している。JavaScript 的な表現である。
“`javascript
function benchmark(proc) {
var start = new Date();
proc();
var end = new Date();
return end.getTime() – start.getTime();
}
console.log(
benchmark(function() {
var x = 15;
for (var i = 0; i < 1000000; i++) {
x *= i;
}
})
);
``` - 高階関数は、イベント処理や非同期処理のためのライブラリでよく利用される記法。 `Promise` と関わってくる。 > * [ES6時代のJavaScript – クックパッド開発者ブログ](http://techlife.cookpad.com/entry/2015/02/02/094607)
> * [Promise – JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise)
[/markdown]