概要: このチュートリアルでは、JavaScript関数がファーストクラスオブジェクトであることを学習します。これは、関数を変数に格納し、他の関数に引数として渡し、他の関数から値として返すことができることを意味します。
変数への関数の格納
関数はJavaScriptでファーストクラスオブジェクトです。つまり、関数を他の型の値のように扱うことができます。
以下は、add()
関数を定義し、関数名をsum
変数に代入する例です。
function add(a, b) {
return a + b;
}
let sum = add;
Code language: JavaScript (javascript)
代入文では、add
識別子の後ろに開き括弧と閉じ括弧を付けません。関数を実行するのではなく、関数を参照します。
これにより、同じ関数を2つの方法で実行できます。例えば、通常どおり次のように呼び出すことができます。
let result = add(10, 20);
Code language: JavaScript (javascript)
あるいは、次のようにsum
変数を通してadd()
関数を呼び出すこともできます。
let result = sum(10,20);
Code language: JavaScript (javascript)
関数を別の関数に渡す
関数は値であるため、関数を引数として別の関数に渡すことができます。
以下は、3つの引数をとるaverage()
関数を宣言した例です。3番目の引数は関数です。
function average(a, b, fn) {
return fn(a, b) / 2;
}
Code language: JavaScript (javascript)
これで、次のようにsum
関数をaverage()
関数に渡すことができます。
let result = average(10, 20, sum);
Code language: JavaScript (javascript)
全てをまとめて
function add(a, b) {
return a + b;
}
let sum = add;
function average(a, b, fn) {
return fn(a, b) / 2;
}
let result = average(10, 20, sum);
console.log(result);
Code language: JavaScript (javascript)
出力
15
関数から関数を返す
関数は値であるため、関数から別の関数を返すことができます。
次のcompareBy()
関数は、プロパティで2つのオブジェクトを比較する関数を返します。
function compareBy(propertyName) {
return function (a, b) {
let x = a[propertyName],
y = b[propertyName];
if (x > y) {
return 1;
} else if (x < y) {
return -1;
} else {
return 0;
}
};
}
Code language: JavaScript (javascript)
a[propertyName]
は、a
オブジェクトのpropertyName
の値を返します。これはa.propertyName
と同等です。ただし、propertyName
に「Discount Price」のようなスペースが含まれる場合は、角括弧表記を使用してアクセスする必要があります。
各製品オブジェクトにname
とprice
の2つのプロパティを持つ製品オブジェクトの配列があるとします。
let products = [
{name: 'iPhone', price: 900},
{name: 'Samsung Galaxy', price: 850},
{name: 'Sony Xperia', price: 700}
];
Code language: JavaScript (javascript)
配列をソートするには、sort()
メソッドを呼び出します。sort()
メソッドは、配列の2つの要素を比較する関数を引数として受け取ります。
例えば、compareBy()
関数から返された関数を渡すことで、名前に基づいて製品オブジェクトをソートできます。
console.log('Products sorted by name:');
products.sort(compareBy('name'));
console.table(products);
Code language: JavaScript (javascript)
出力
Products sorted by name:
┌─────────┬──────────────────┬───────┐
│ (index) │ name │ price │
├─────────┼──────────────────┼───────┤
│ 0 │ 'Samsung Galaxy' │ 850 │
│ 1 │ 'Sony Xperia' │ 700 │
│ 2 │ 'iPhone' │ 900 │
└─────────┴──────────────────┴───────┘
Code language: plaintext (plaintext)
同様に、価格で製品オブジェクトをソートすることもできます。
// sort products by prices
console.log('Products sorted by price:');
products.sort(compareBy('price'));
console.table(products);
Code language: JavaScript (javascript)
出力
Products sorted by price:
┌─────────┬──────────────────┬───────┐
│ (index) │ name │ price │
├─────────┼──────────────────┼───────┤
│ 0 │ 'Sony Xperia' │ 700 │
│ 1 │ 'Samsung Galaxy' │ 850 │
│ 2 │ 'iPhone' │ 900 │
└─────────┴──────────────────┴───────┘
Code language: JavaScript (javascript)
全てをまとめて。
function compareBy(propertyName) {
return function (a, b) {
let x = a[propertyName],
y = b[propertyName];
if (x > y) {
return 1;
} else if (x < y) {
return -1;
} else {
return 0;
}
};
}
let products = [
{ name: 'iPhone', price: 900 },
{ name: 'Samsung Galaxy', price: 850 },
{ name: 'Sony Xperia', price: 700 },
];
// sort products by name
console.log('Products sorted by name:');
products.sort(compareBy('name'));
console.table(products);
// sort products by price
console.log('Products sorted by price:');
products.sort(compareBy('price'));
console.table(products);
Code language: JavaScript (javascript)
JavaScript関数はファーストクラスオブジェクトのさらなる例
次の例では、センチメートル単位の長さをインチ単位に変換し、その逆を行う2つの関数を定義します。
function cmToIn(length) {
return length / 2.54;
}
function inToCm(length) {
return length * 2.54;
}
Code language: JavaScript (javascript)
次のconvert()
関数は2つのパラメータを持ちます。最初の引数は関数で、2番目の引数は最初の引数に基づいて変換される長さです。
function convert(fn, length) {
return fn(length);
}
Code language: JavaScript (javascript)
cm
をin
に変換するには、convert()
関数を呼び出し、cmToIn
関数をconvert()
関数の最初の引数として渡します。
let inches = convert(cmToIn, 10);
console.log(inches);
Code language: JavaScript (javascript)
出力
3.937007874015748
Code language: CSS (css)
同様に、インチからセンチメートルへの長さを変換するには、次のようにinToCm
関数をconvert()
関数に渡します。
let cm = convert(inToCm, 10);
console.log(cm);
Code language: JavaScript (javascript)
出力
25.4
Code language: CSS (css)
全てをまとめて。
function cmToIn(length) {
return length / 2.54;
}
function inToCm(length) {
return length * 2.54;
}
function convert(fn, length) {
return fn(length);
}
let inches = convert(cmToIn, 10);
console.log(inches);
let cm = convert(inToCm, 10);
console.log(cm);
Code language: JavaScript (javascript)
出力
3.937007874015748
25.4
Code language: CSS (css)
まとめ
- 関数はJavaScriptでファーストクラスオブジェクトです。
- 関数を引数として他の関数に渡したり、値として他の関数から返したり、変数に格納したりできます。