なんとなくで使っていたので、整理を兼ねて文字に起こします。
はじめに
Javascriptには、標準組み込みオブジェクト(Standard built-in objects)というグローバル領域にあるオブジェクトがあります。
この標準組み込みオブジェクトにオブジェクトの基本となるオブジェクト、Object
,
Function
,Boolean
,Symbol
があります。
今回はこの中のFunction
オブジェクトについて、深掘りしていきます。
Javascriptの全ての関数はこのFunction
オブジェクトであり、 Function
オブジェクトは functions
のメソッドを持ちます。
thisについて
Function
のメソッドで使うためにはthis
を理解しておく必要があります。
個人的に、下記が一番わかりやすかったです。
thisはオブジェクト自身を指し、.
の前のオブジェクトが指定されます。
関数の呼び出しをした時、オブジェクトで実行している場合、そのオブジェクトをthisとして参照できます。
オブジェクトを指定しない場合は、グローバルオブジェクトまたはundefinedが指定されます。
別のオブジェクトを指定した場合、その別のオブジェクトがthisとして参照されます。
// 1. オブジェクトを指定している
const obj1 = {
prop1: 1,
func1: function() { console.log(this) }
};
obj1.func1();
// => {prop1: 1, func1: ƒ}
// 2. オブジェクトを指定していない
const func2 = obj1.func1;
func2();
// => undefinedまたはグローバルオブジェクト (ブラウザで実行している場合はwindow)
// 3. 別のオブジェクトを指定する
const obj2 = {
prop2: 2
}
obj2.func2 = obj1.func1;
obj2.func2();
// => {prop2: 2, func2: ƒ}
標準組み込みオブジェクトのFunctionのインスタンスメソッド
下記のメソッドが用意されています。
Function.prototype.call()
第一引数にthisの値、第二引数以降は呼び出し先の引数として渡されて、関数を呼び出せます。
const obj1 = {
prop1: 1,
func1_1: function(prop1_1) { console.log(prop1_1, this) },
func1_2: function(prop1_1, prop1_2) { console.log(prop1_1, prop1_2, this) }
};
const obj2 = {
prop2: 2
};
obj1.func1_1.call(obj2, 3);
// => 3 {prop2: 2}
obj1.func1_1.call(obj2, 3, 4);
// => 3 {prop2: 2}
obj1.func1_2.call(obj2, 3, 4);
// => 3 4 {prop2: 2}
obj1.func1_2.call(obj2, [3, 4, 5, 6], 7);
// => [3, 4, 5, 6] 7 {prop2: 2}
obj1.func1_1.call(1, 3); // 数値を指定するとNumberのオブジェクトとして指定される
// => 3 Number {1}
obj1.func1_1.call('1', 3); // 文字列を指定するとStringのオブジェクトとして指定される
// => 3 String {'1'}
obj1.func1_1.call(null, 3); // nullやundefinedを指定すると、
// => 3 undefinedまたはグローバルオブジェクト
Function.prototype.apply()
第一引数にthisの値、第二引数は呼び出し先の引数を列挙したArrayを指定して、関数を呼び出せます。
const obj1 = {
prop1: 1,
func1: function(prop) { console.log(prop, this) }
};
const obj2 = {
prop2: 2
}
obj1.func1_1.apply(obj2, 3);
// => Arrayでないので、error
obj1.func1_1.apply(obj2, [3]);
// => 3 {prop2: 2}
obj1.func1_1.apply(obj2, [3, 4]);
// => 3 {prop2: 2}
obj1.func1_2.apply(obj2, [3, 4]);
// => 3 4 {prop2: 2}
Function.prototype.bind()
第一引数にthisの値して、新しく関数を作成します。
const obj1 = {
prop1: 1,
func1: function(prop) { console.log(prop, this) }
};
const obj2 = {
prop2: 2
};
const func1_1_bind = obj1.func1_1.bind(obj2);
const func1_2_bind = obj1.func1_2.bind(obj2);
func1_1_bind(3);
// => 3 {prop2: 2}
func1_1_bind(3, 4);
// => 3 {prop2: 2}
func1_2_bind(3, 4);
// => 3 4 {prop2: 2}
使い道を考える
下記のような、classのインスタンスメソッドをそのインスタンス外で使いたい時などで使える
class Animal {
name = 'animal';
display_name() {
console.log(this.name)
}
}
class Fish {
name = 'fish';
}
const animal = new Animal();
const display_name1 = animal.display_name;
// 1. 別のオブジェクトのプロパティでメソッドを使う
const fish = new Fish();
display_name1.call(fish);
// => fish
// 2. インスタンスメソッドをそのインスタンス外で使う
const display_name2 = animal.display_name.bind(animal);
display_name2();
// => animal
終わり
調べるついでにQiita書こうと思うと、理解する意欲が変わるので今後続けていきたい