概要: このチュートリアルでは、JavaScript のすべての関数の型である JavaScript の `Function` 型について学習します。
JavaScript 関数型入門
JavaScript では、すべての関数はオブジェクトです。それらは `Function` 型のインスタンスです。関数はオブジェクトであるため、他のオブジェクトと同様にプロパティとメソッドを持ちます。
関数のプロパティ
各関数には、`length` と `prototype` の 2 つの重要なプロパティがあります。
- `length` プロパティは、関数宣言で指定された名前付き引数の数を決定します。
- `prototype` プロパティは、実際の関数オブジェクトを参照します。
以下の例を参照してください
function add(x, y) {
return x + y;
}
console.log(add.length); // 2
console.log(add.prototype); // Object{}
Code language: JavaScript (javascript)
`add()` 関数は、2 つの引数 `x` と `y` を受け取ります。そのため、`length` プロパティは 2 を返します。
new.target
通常、関数は次のように呼び出します
let result = add(10,20);
console.log(result); // 30
Code language: JavaScript (javascript)
また、`new` キーワードを使用してコンストラクタとして関数を呼び出すこともできます
let obj = new add(10,20);
Code language: JavaScript (javascript)
ES6 は、`new` 演算子を使用して関数またはコンストラクタが呼び出されたかどうかを検出できる ` new.target`擬似プロパティを導入しました。
関数が通常呼び出される場合、`new.target` は `undefined` です。ただし、`new` キーワードを使用してコンストラクタとして関数が呼び出される場合、`new.target` はコンストラクタへの参照を返します。
例:
function add(x, y) {
console.log(new.target);
return x + y;
}
let result = add(10, 20);
let obj = new add(10, 20);
Code language: JavaScript (javascript)
出力
undefined
[Function: add]
Code language: JavaScript (javascript)
`new.target` を使用すると、関数の呼び出し方法を制御できます。
たとえば、`add()` 関数を `new` キーワードを使用してコンストラクタとして呼び出さないようにするには、次のように `new.target` をチェックしてエラーをスローできます。
function add(x, y) {
if (new.target) {
throw 'The add function cannot be called as a constructor';
}
return x + y;
}
let obj = new add(10, 20);
console.log(obj);
Code language: JavaScript (javascript)
関数のメソッド: apply、call、および bind
関数オブジェクトには、`apply()`、`call()`、`bind()` の 3 つの重要なメソッドがあります。
apply() および call() メソッド
`apply()` と `call()` メソッドは、指定された `this` 値と引数を使用して関数を呼び出します。
`apply()` と `call()` の違いは、`apply()` メソッドには引数を配列のようなオブジェクトとして渡す必要があるのに対し、`call()` 関数には引数を個別に渡す必要があることです。例:
let cat = { type: 'Cat', sound: 'Meow' };
let dog = { type: 'Dog', sound: 'Woof' };
const say = function (message) {
console.log(message);
console.log(this.type + ' says ' + this.sound);
};
say.apply(cat, ['What does a cat say?']);
say.apply(dog, ['What does a dog say?']);
Code language: JavaScript (javascript)
出力
What does a cat sound?
Cat says Meow
What does a dog sound?
Dog says Woof
この例では
まず、2 つのプロパティを持つ `cat` と `dog` の 2 つのオブジェクトを宣言します
let cat = { type: 'Cat', sound: 'Meow' };
let dog = { type: 'Dog', sound: 'Woof' };
Code language: JavaScript (javascript)
次に、1 つの引数を受け取る `say()` 関数を定義します
const say = function (message) {
console.log(message);
console.log(this.type + ' says ' + this.sound);
};
Code language: JavaScript (javascript)
3 番目に、`apply()` メソッドを使用して `say()` 関数を呼び出します
say.apply(cat, ['What does a cat say?']);
Code language: CSS (css)
この例では、`apply()` メソッドの最初の引数は `cat` オブジェクトです。したがって、`say()` 関数の `this` オブジェクトは `cat` オブジェクトを参照します。
4 番目に、`say()` 関数を呼び出し、`dog` オブジェクトを渡します
say.apply(dog, ['What does a dog say?']);
Code language: CSS (css)
この例では、`say()` 関数の `this` は `dog` オブジェクトを参照します。
`call()` メソッドは、関数を呼び出す方法を除いて `apply()` メソッドに似ています。
say.call(cat, 'What does a cat say?');
say.call(dog, 'What does a dog say?');
Code language: JavaScript (javascript)
bind() メソッド
`bind()` メソッドは、`this` 値が提供するオブジェクトにバインドされた新しい関数インスタンスを作成します。例:
まず、`car` という名前のオブジェクトを定義します
let car = {
speed: 5,
start: function() {
console.log('Start with ' + this.speed + ' km/h');
}
};
Code language: JavaScript (javascript)
次に、`aircraft` という名前の別のオブジェクトを定義します
let aircraft = {
speed: 10,
fly: function() {
console.log('Flying');
}
};
Code language: JavaScript (javascript)
`aircraft` には `start()` メソッドがありません。航空機を始動するには、`car` オブジェクトの `start()` メソッドの `bind()` メソッドを使用できます
let taxiing = car.start.bind(aircraft);
Code language: JavaScript (javascript)
このステートメントでは、`car` オブジェクトの `start()` メソッド内の `this` 値を `aircraft` オブジェクトに変更します。`bind()` メソッドは、`taxiing` 変数に割り当てられる新しい関数を返します。
これで、`taxiing` 変数を使用して `start()` メソッドを呼び出すことができます
taxiing();
次のメッセージが表示されます
Start with 10 km/h
Code language: JavaScript (javascript)
以下は、`call()` メソッドを使用して `aircraft` オブジェクトで `start()` メソッドを呼び出しています
car.start.call(aircraft);
Code language: CSS (css)
ご覧のとおり、`bind()` メソッドは後で実行できる新しい関数を生成するのに対し、`call()` メソッドは関数をすぐに実行します。これが `bind()` と `call()` メソッドの主な違いです。
技術的には、`aircraft` オブジェクトは `bind()`、`call()`、または `apply()` メソッドを介して `car` オブジェクトの `start()` メソッドを借用します。
このため、`bind()`、`call()`、および `apply()` メソッドは、借用関数としても知られています。
概要
- すべての関数は `Function` 型のインスタンスであり、プロパティとメソッドを持つオブジェクトです。
- 関数には、`length` と `prototype` の 2 つの重要なプロパティがあります。
- 関数には、`call()`、`apply()`、`bind()` の 3 つの重要なメソッドもあります。