本文整理JavaScript Function.prototype下bind()、call()、apply()方法,亦可參見MDN連結。
Function.prototype.bind()
理解為「綁定」,要「綁定」something給前方的function
綁定什麼呢?
綁定前方這個function執行時,所需要的this和parameter
bind()的參數第一項一定是this,this可以為空值null,比如說你前方的function沒用到this.something,那就不需要特地綁this;第一項以後的參數,依序提供給前方的function作為parameter。
const printSubscription = function(){
console.log(this.subscription)
}
const pekora = {
subscription:"145萬",
age:111
}
const showPekoraSubscription = printSubscription.bind(pekora)
showPekoraSubscription()
//145萬
bind()會建立一個新的Bound Function,因此和call()、apply()不同,綁完後是沒有包括執行這個新的Bound Function的
Function.prototype.call()
理解為「呼叫」,someFunction.call(this, arg1, arg2, ...)表示在呼叫執行someFunction時,給定this以及參數args
arg1、arg2、arg3等,依序填入給someFunction作為parameters
call()在各大前端框架中廣泛使用,MDN寫了兩種範例:物件建構子綁call()、匿名函數綁call()
物件建構子綁call()
function Vtuber(name, generation) {
this.name = name;
this.generation = generation;
if (generation > 5 || generation < 0) throw RangeError("The generation is out of range.");
return this;
}
function Hololive(name, generation) {
Vtuber.call(this, name, generation);
this.company = "Hololive";
}
Hololive.prototype = new Vtuber()
const Pekora = new Hololive("Pekora",3)
console.log(Pekora)
// Vtuber { name: 'Pekora', generation: 3, company: 'Hololive' }
匿名函數綁call()
const Vtubers = [
{ name: "Pekora", generation: "3" },
{ name: "Nene", generation: "5" },
];
for (let i = 0; i < Vtubers.length; i++) {
(function (i) {
this.print = function () {
console.log("# " + this.name + "is Hololive " + this.generation + " generation.");
};
this.print();
}.call(Vtubers[i], i));
}
// # Pekorais Hololive 3 generation.
// # Neneis Hololive 5 generation.
Function.prototype.apply()
理解為「使用、套用」,someFunction.apply(this, [arg1, arg2, ...])表示在呼叫執行someFunction時,給定this以及陣列內的參數args。
跟call()的差別就在於call()的args是逗號區隔依序填入,但apply()是把args包一起放陣列內
function Hololive(name, generation) {
Vtuber.apply(this, [name, generation]);
this.company = "Hololive";
}