概要: このチュートリアルでは、JavaScriptのアロー関数を使用して、関数式をより簡潔に記述する方法を学習します。
JavaScriptアロー関数の入門
ES6のアロー関数は、関数式に比べてより短い構文で記述できる代替手段を提供します。
次の例は、2つの数値の合計を返す関数式を定義しています。
let add = function (x, y) {
return x + y;
};
console.log(add(10, 20)); // 30
Code language: JavaScript (javascript)
次の例は、上記のadd()
関数式と等価ですが、代わりにアロー関数を使用しています。
let add = (x, y) => x + y;
console.log(add(10, 20)); // 30;
Code language: JavaScript (javascript)
この例では、アロー関数は1つの式x + y
を持っているため、その式の結果を返します。
ただし、ブロック構文を使用する場合は、return
キーワードを指定する必要があります。
let add = (x, y) => { return x + y; };
Code language: JavaScript (javascript)
typeof
演算子は、アロー関数の型を示すfunction
を返します。
console.log(typeof add); // function
Code language: JavaScript (javascript)
アロー関数も、次の例に示すようにFunction型のインスタンスです。
console.log(add instanceof Function); // true
Code language: JavaScript (javascript)
複数のパラメーターを持つJavaScriptアロー関数
アロー関数が2つ以上のパラメーターを持つ場合、次の構文を使用します。
(p1, p2, ..., pn) => expression;
Code language: PHP (php)
次の式
=> expression
Code language: PHP (php)
は、次の式と同等です。
=> { return expression; }
Code language: PHP (php)
たとえば、数値の配列を降順にソートするには、配列オブジェクトのsort()
メソッドを次のように使用します。
let numbers = [4,2,6];
numbers.sort(function(a,b){
return b - a;
});
console.log(numbers); // [6,4,2]
Code language: JavaScript (javascript)
アロー関数の構文を使用すると、コードがより簡潔になります。
let numbers = [4,2,6];
numbers.sort((a,b) => b - a);
console.log(numbers); // [6,4,2]
Code language: JavaScript (javascript)
単一のパラメーターを持つJavaScriptアロー関数
アロー関数が単一のパラメーターを受け取る場合、次の構文を使用します。
(p1) => { statements }
Code language: PHP (php)
括弧を省略することもできます。
p => { statements }
Code language: PHP (php)
次の例では、アロー関数をmap()
メソッドの引数として使用しており、文字列の配列を文字列の長さの配列に変換します。
let names = ['John', 'Mac', 'Peter'];
let lengths = names.map(name => name.length);
console.log(lengths);
Code language: JavaScript (javascript)
出力
[ 4, 3, 5 ]
Code language: JSON / JSON with Comments (json)
パラメーターを持たないJavaScriptアロー関数
アロー関数がパラメーターを持たない場合、次のように括弧を使用する必要があります。
() => { statements }
Code language: PHP (php)
例えば
let logDoc = () => console.log(window.document);
logDoc();
Code language: JavaScript (javascript)
パラメーター定義とアローの間の改行
JavaScriptでは、アロー関数のパラメーター定義とアロー(=>
)の間に改行を入れることはできません。
たとえば、次のコードはSyntaxError
を引き起こします。
let multiply = (x,y)
=> x * y;
Code language: JavaScript (javascript)
ただし、次のコードは正常に動作します。
let multiply = (x,y) =>
x * y;
Code language: JavaScript (javascript)
JavaScriptでは、次の例に示すように、パラメーター間に改行を入れることができます。
let multiply = (
x,
y
) =>
x * y;
Code language: JavaScript (javascript)
アロー関数本体内のステートメントと式
JavaScriptでは、次の例に示すように、式は値に評価されます。
10 + 20;
ステートメントは、次のような特定のタスクを実行します。
if (x === y) {
console.log('x equals y');
}
Code language: JavaScript (javascript)
アロー関数の本体に式を使用する場合は、中括弧を使用する必要はありません。
let square = x => x * x;
Code language: JavaScript (javascript)
ただし、ステートメントを使用する場合は、次の例のように、中括弧で囲む必要があります。
let except = msg => {
throw msg;
};
Code language: JavaScript (javascript)
JavaScriptアロー関数とオブジェクトリテラル
次の例を考えてみましょう。
let setColor = function (color) {
return {value: color}
};
let backgroundColor = setColor('Red');
console.log(backgroundColor.value); // "Red"
Code language: JavaScript (javascript)
setColor()
関数式は、value
プロパティがcolor
引数に設定されたオブジェクトを返します。
アロー関数からオブジェクトリテラルを返すために次の構文を使用すると、エラーが発生します。
p => {object:literal}
Code language: PHP (php)
たとえば、次のコードはエラーの原因となります。
let setColor = color => {value: color };
Code language: JavaScript (javascript)
ブロックとオブジェクトリテラルの両方が中括弧を使用するため、JavaScriptエンジンはブロックとオブジェクトを区別できません。
これを修正するには、オブジェクトリテラルを括弧で囲む必要があります。
let setColor = color => ({value: color });
Code language: JavaScript (javascript)
アロー関数と通常の関数
アロー関数と通常の関数には、2つの主な違いがあります。
- まず、アロー関数では、
this
、arguments
、super
、new.target
はレキシカルです。つまり、アロー関数は、これらの変数(または構成体)を囲んでいるレキシカルスコープから使用します。 - 第二に、アロー関数は関数コンストラクターとして使用できません。
new
キーワードを使用してアロー関数から新しいオブジェクトを作成しようとすると、エラーが発生します。
JavaScriptアロー関数とthis値
JavaScriptでは、新しい関数は独自のthis
値を定義します。ただし、アロー関数ではこれは当てはまりません。次の例を参照してください。
function Car() {
this.speed = 0;
this.speedUp = function (speed) {
this.speed = speed;
setTimeout(function () {
console.log(this.speed); // undefined
}, 1000);
};
}
let car = new Car();
car.speedUp(50);
Code language: JavaScript (javascript)
setTimeout()
関数の匿名関数内では、this.speed
はundefined
です。その理由は、匿名関数のthis
がspeedUp()
メソッドのthis
をシャドウイングしているためです。
これを修正するには、匿名関数内でシャドウイングされない変数にthis
値を代入します。
function Car() {
this.speed = 0;
this.speedUp = function (speed) {
this.speed = speed;
let self = this;
setTimeout(function () {
console.log(self.speed);
}, 1000);
};
}
let car = new Car();
car.speedUp(50); // 50;
Code language: JavaScript (javascript)
匿名関数とは異なり、アロー関数は独自のthis
コンテキストを作成するのではなく、囲んでいるコンテキストのthis
値を取得します。次のコードは期待通りに動作するはずです。
function Car() {
this.speed = 0;
this.speedUp = function (speed) {
this.speed = speed;
setTimeout(
() => console.log(this.speed),
1000);
};
}
let car = new Car();
car.speedUp(50); // 50;
Code language: JavaScript (javascript)
JavaScriptアロー関数とargumentsオブジェクト
アロー関数にはarguments
オブジェクトがありません。例えば
function show() {
return x => x + arguments[0];
}
let display = show(10, 20);
let result = display(5);
console.log(result); // 15
Code language: JavaScript (javascript)
showMe()
関数内のアロー関数はarguments
オブジェクトを参照しています。しかし、このarguments
オブジェクトはアロー関数ではなく、show()
関数に属しています。
また、アロー関数にはnew.target
キーワードもありません。
JavaScriptアロー関数とprototypeプロパティ
function
キーワードを使用して関数を定義する場合、その関数はprototype
と呼ばれるプロパティを持ちます。
function dump( message ) {
console.log(message);
}
console.log(dump.hasOwnProperty('prototype')); // true
Code language: JavaScript (javascript)
しかし、アロー関数にはprototype
プロパティがありません。
let dump = message => console.log(message);
console.log(dump.hasOwnProperty('prototype')); // false
Code language: JavaScript (javascript)
アロー関数の構文はよりクリーンであるため、コールバックとクロージャーにはアロー関数を使用することをお勧めします。
まとめ
(...args) => expression;
を使用してアロー関数を定義します。- 複数ステートメントを持つアロー関数を定義するには、
(...args) => { statements }
を使用します。 - アロー関数には、
this
またはsuper
へのバインディングがありません。 - アロー関数には、
arguments
オブジェクト、new.target
キーワード、prototype
プロパティがありません。