JavaScriptでは、関数はFunctionオブジェクトである。
なので、ほかのオブジェクトと同じように使用することができる。
ex)
・変数や、オブジェクトのプロパティ、配列要素に代入できる
・関数の引数にできる
・関数の戻り値にできる
・プロパティやメソッドを持つことができる
・無名のリテラルとして表現できる(無名関数)
・動的に生成できる
this
関数が呼び出されるたびにthisの値が決定される。
thisの値は、「関数が呼び出されたときにその関数が所属していたオブジェクトへの参照」。
下の例では所属していたオブジェクトが[person‗1]でありこれが=thisなのである。
オブジェクトのnameプロパティがtomなのでコンソールのような結果になる。
let person_1 = {
name: "tom",
say: function() {
console.log("hello", this.name);
}
}
person_1.say();
//コンソール
hello tom
person_1.say();は関数への参照である。このプロパティはほかのオブジェクトのプロパティに代入できる。
たとえば、
let person_2 = { name : "billy"}
このようなオブジェクトを作る。
person_2.のsayプロパティにperson_1.のsayプロパティを代入してみる
person_2.say = person_1.say
これをよびだすと
person2.say()
//コンソール
hello billy
となる。
person_2のsayプロパティのthisはperson_2を指しており、person_2のnameプロパティはbillyのためである。
javascriptの関数は、様々なオブジェクトから参照され、その都度thisは変わっていくのである。
apply
JavaScriptの関数はオブジェクトであるため、関数自身がメソッドを持っている。
その中には、thisを操作できるメソッドもいくつかある。そのうちの一つがapply。
第1引数にthis、第2引数はそのまま関数の引数となる。
引数が配列。
function say(greeting, honorifics) {
console.log(greeting + " " + honorifics + this.name)
}
let suda = {name:"sudaMasaki"}
say.apply(suda,["hello","Mr."])
//コンソール
hello Mr.sudaMasaki
.applyメソッドの第1引数はsuda = this。
第2引数は配列で["hello","Mr."]これがsay関数の第1引数 greeting = "hello" , honorifics = "Mr" となる。
call
.applyメソッドとほぼ同じ。。
引数が配列がカンマ区切りのリスト。
function say(greeting, honorifics) {
console.log(greeting + " " + honorifics + this.name)
}
let suda = {name:"sudaMasaki"}
say.call(suda,"hello","Mr.")
//コンソール
hello Mr.sudaMasaki
bind
bind()は、thisの値を最初に固定して関数を作る。
第一引数に指定したものが、thisとなる。
この方法で作られた関数は、今後どのような文脈で呼ばれても、thisの値は最初に設定したもののまま、変わることがない。
function sayNameForAll(label){
console.log(label + 'の名前は、' + this.name);
};
var man = {
name: 'masaki'
};
var woman = {
name: 'nana'
};
var sayNameForMan = sayNameForAll.bind(man); //thisはmanを指す
sayNameForMan('男性'); //男性の名前は、masaki
var sayNameForWoman = sayNameForAll.bind(woman); //thisはwomanを指す
sayNameForWoman('女性'); //女性の名前は、nana
woman.sayName = sayNameForMan; //sayNameForManのthisはmanのまま
woman.sayName('女性'); //女性の名前は、masaki