理解 JavaScript 中的绑定、调用和应用
就像在现实世界中向烧伤区域泼冷水一样,我们也可以apply
在数字世界中为我们的函数调用添加附加信息。
最近,我试图澄清JavaScript中 this 关键字的困惑,并简要介绍了bind
和call
。但这次,我想对它们进行更深入的探讨,并对 进行一些补充apply
。
让我们按照标题的顺序进行,首先从 bind 开始。但首先,我们需要一些代码来演示这三个方法,请看下面的代码:
const currentYear = new Date().getFullYear();
const spongebob = {
name: 'Spongebob Squarepants',
dob: 1986,
species: 'sea sponge',
greet(qoute) {
console.log(`Hey, it's me, ${this.name} and I'm ${currentYear - this.dob} years old`);
qoute && console.log(qoute); // If we have a quote, log it out
}
};
const patrick = {
name: 'Patrick Star',
dob: 1978,
species: 'starfish',
greet(qoute) {
console.log(`Hey, it's me, ${this.name} and I'm ${currentYear - this.dob} years old`);
qoute && console.log(qoute);
}
};
绑定
bind
在 JavaScript 中,它用于将特定上下文绑定到函数。当您调用一个函数时funky
,例如:funky.bind(soul)
,实际上是在创建一个新函数,其上下文this
设置为 soul 的值。请记住,这不会修改原始函数,也不会调用它。
// Since bind doesn't modify the original function, this.name will still be "Spongebob".
spongebob.greet.bind(patrick);
spongebob.greet(); // Hey, it's me, Spongebob...
// Assigning the bound greet to a variable and calling that will give back Patrick's details.
const greetPatrick = spongebob.greet.bind(patrick);
greetPatrick(); // Hey, it's me, Patrick...
上面的代码示例演示了bind
不会改变实际函数,而是创建一个全新的函数。greetPatrick()
第二次调用 时,由于绑定上下文,即使调用了 ,我们仍然会返回 Patrick 的详细信息spongbob.greet
。
称呼
与 不同bind
,call
它实际上会立即使用指定的上下文调用该函数。我们来看看下面的代码:
// This will immediately calls greet with the context of patrick.
spongebob.greet.call(patrick);
// Since we call the function right away, the value of greetPatrick will be the return value
// When we don't have an explicit return statement eg.: 'return true;', "undefined" is returned implicitly
const greetPatrick = spongebob.greet.call(patrick);
console.log(greetPatrick); // undefined
spongebob.greet.call(spongebob, 'I\'m a good noodle!');
在第 9 行,我们用spongebob
上下文调用 Spongebob,并将字符串作为参数传入。这一行代码本质上等同于以下内容:
spongebob.greet('I\'m a good noodle!');
申请
Apply
函数为call
。两者之间的唯一区别是,whilecall
接受参数列表,apply
而接受参数数组。
patrick.greet.apply(patrick, ['Is mayonnaise an instrument?']);
call
注意和之间的区别apply
。一个使用数组调用,而另一个则不使用。如果我们有多个参数,它们将如下所示:
// Accepts list of arguments
spongebob.greet.call(spongebob, 'Believe it or not', 'I\'m a good noodle!');
// Accepts array of arguments
patrick.greet.apply(patrick, ['Is mayonnaise an instrument?', 'Mayonnaise is not an instrument 😔']);
我想这三者之间的区别就到此为止了。让我们回顾一下,然后得出结论。
结论
- 当您想要将上下文绑定到稍后
bind
调用的函数时使用。 - 如果您想立即调用该函数,请使用
call
或。apply
当谈论宇宙时,最大的问题是call
——apply
选择哪一个?这真的取决于你的选择。
但如果我们看看哪一个表现更好,似乎获胜者是 call。
文章来源:https://dev.to/flowforfrank/understanding-bind-call-and-apply-in-javascript-24k1