JavaScriptの関数を関数に入れる不思議
JavaScriptでは、
・関数を代入できる
・関数を関数の引数に渡すことができる
というのがあって個人的にはすごく不思議な感じがする。
function kansu() { window.alert("関数aaaを実行しました"); } var aaa = kansu; aaa();
functionを使うことで関数に名前を付けずに(無名関数を)、代入することもできる。
var bbb = function () { window.alert("関数bbbを実行しました"); }
無名関数はコンストラクタ(オブジェクトを生成するための関数)の中で使われることが多い。
function Wizard(hp, mp) { this.hp = hp; this.mp = mp; this.fire = function () { window.alert("炎で攻撃"); } this.heal = function () { window.alert("味方を回復"); } } var suneo = new Wizard(10,5); suneo.fire();
関数を関数に入れる(コールバック関数)
JavaScriptでは関数に関数を入れることができる。
入れられた関数のことをコールバック関数と呼ぶ。
以下の例では、filter関数にfunctionを入れて、その結果をhigh変数に入れている。
var cards = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']; var high = cards.filter(function(c) {return isNaN(c);}); window.alert(high);
cardsで配列を定義。cards.filterメソッドはfilterに与えられた関数によって実装されたテストに合格した(trueになった)全ての配列からなる新しい配列が生成される。
つまりfilterの引数に無名関数が渡されている。その無名関数への引数はcardsの要素が順番に評価される。isNAN関数は引数が数値じゃなければtrueが。数値ならfalseが返る。
ここではtrueである数値じゃない要素A J Q Kで新たに生成された配列が返る。
JavaScriptのアロー関数と使い方
前章、上の3行のうちまんなかの1行は次のように書き換えることが出来る。
var high = cards.filter(function(c) {return isNaN(c);});
↓
var high = cards.filter(c => isNaN(c));
つまりfunction()を省略し、=>を入れて{}を省略し、returnを省略できる。
記号の羅列の様にしか見えない。覚えるのは無理だ。
配列のsort関数とコールバック関数による並べ替え例
配列arrを宣言し、arr.sort()を活用する。
arrの要素を文字列に置き換えてからUTF16コード順でソートされる。
配列arr自身はソート前後で中身が入れ替わる。
※ということは数字をソートすると数字順にならない
//事例 const array1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; array1.sort(); //文字列に変換してからソートするので数字順にならない console.log(array1); //結果は[1,10,11,12,2,3,4,5,6,7,8,9]
コールバック関数を入れて自分でソート順を指定
sort()関数の引数に関数(コールバック関数ahoaho)を入れてソート順を自分で指定することができる。
arr.sort(ahoaho);
と言う風に関数名を入れればよい。()や引数は無用。
そして、
・ahoaho(a, b)が0未満の場合、a→bの順でソート
・ahoaho(a, b)が0の場合、aとbは変更せず
・ahoaho(a, b)が0より大きい場合、b→aの順でソート
とソート順を指示することができる。
なぜ2つの引数a,bと書くか。これは各種ソートのアルゴリズムを理解していれば理解できる。
ソートは2つの値を比較して入れ替えるのを繰り返すためaとbを比較すればソートが可能なため。
アルファベットのaとbである理由は慣習的なモノ。
コールバック関数の中は原則こういう風に-1/0/1をreturnするように関数を定義する↓。
//昇順ソート function ahoaho(a, b) { if(a < b) { return -1; } if(a > b) { return 1; } return 0; }
返り値(-1/0/1)に従って配列の要素が並べ替えが行われる。
単純にarrの中を「数字」で比較する場合は、
function ahoaho(a, b) { return a - b; }
こう簡潔に書くことが出来、原則通り動く。数字の昇順でソートされる。(InfinityやNaNが無ければ)
See the Pen
sort-jun-kakunin by pghappy (@pghappy)
on CodePen.
無名関数を使って定義すると便利。
var numbers = [4, 2, 5, 1, 3]; numbers.sort(function(a, b) { return a - b; });
アロー関数でも記述できる。
numbers.sort((a, b) => a - b);
arrの中を「文字列の名前順」昇順にソートするには
var items = ['Banana', 'Apple', 'Durian', 'Cherry']; window.alert("並べ替え前:" + items); items.sort(function(a, b) { if (a < b) return -1; if (a > b) return 1; return 0; }); window.alert("昇順ソート後:" + items); function ahoaho(a,b) { if (a > b) return -1; if (a < b) return 1; return 0; } items.sort( ahoaho ); window.alert("降順ソート後:" + items);
とすれば動く。無名関数を使って記述すると楽↓。
var items = ['Banana', 'Apple', 'Cherry']; items.sort(function(a, b) { if (a < b) return -1; if (a > b) return 1; return 0; });
名前の降順でソートするには
items.sort(function(a, b) { if (a > b) return -1; if (a < b) return 1; return 0; });
とやればOKなのは理解できるだろう。


