javascript晚绑定

by Kevin Kononenko

凯文·科诺年科(Kevin Kononenko)

JavaScript的应用,调用和绑定通过托管野餐来解释 (JavaScript’s apply, call, and bind explained by hosting a cookout)

If you have ever been in charge of operating the grill at a family event or party, then you can understand apply, call and bind in JavaScript.

如果您曾经在家庭活动或聚会上负责过烤架的操作,那么您可以理解JavaScript中的申请,调用和绑定。

If you want to write clear code that you (or a teammate) can re-read at a later date, here is one common rule: don’t repeat yourself!

如果您想编写清晰的代码,以便您(或队友)以后可以重新阅读,请遵循以下一条常见规则:不要重复自己!

If you create repetitive methods or functions, your code will be harder to maintain going forward. You will create bugs simply by failing to remember to update multiple versions of the same code.

如果您创建重复的方法或函数,则您的代码将难以维护。 您仅会因忘记记住更新同一代码的多个版本而创建bug。

If you have a firm understanding of the concept of this in JavaScript, you know that this can be especially challenging as you try to track execution context. That is the relationship between the function and the object that it is being called upon.

如果你有一个坚定的认识这个在JavaScript中的概念 ,你知道,这可能是特别具有挑战性的,当你试图跟踪执行上下文 。 那就是函数和被调用的对象之间的关系。

In order to write cleaner code, you can use the apply, call, and bind methods to purposefully manipulate execution context. Different objects can share methods without rewriting them for each individual object.

为了编写更简洁的代码,可以使用apply,call和bind方法有目的地操纵执行上下文。 不同的对象可以共享方法,而无需为每个对象重写它们。

Apply, call, and bind are sometimes called function methods, since they are called alongside a function.

Apply,Call和Bind有时称为函数方法 ,因为它们是在函数旁边调用的。

If you are looking for a more technical explanation, I recommend the guide from JavaScriptIsSexy.

如果您正在寻找更多技术说明,我建议使用JavaScriptIsSexy的指南。

确切地说,这像烹饪吗? (How is this like cooking, exactly?)

These three methods are kind of like applying cooking skills to prepare food for a cookout. Think of the different contexts that you might need to cook:

这三种方法有点像应用烹饪技巧来准备烹饪食物。 考虑一下您可能需要烹饪的不同背景:

  1. A general meal that you can cook pretty much any time and make everyone happy (pasta and sauce)您可以随时烹饪几乎可以使每个人都开心的普通餐(意大利面和酱汁)
  2. A cookout that might also be a party (burgers, hot dogs etc.)可能也是聚会的野炊活动(汉堡,热狗等)
  3. A fancy dinner for just you and your partner (fish and wine)只为您和您的伴侣的花式晚餐(鱼和酒)
  4. Making dessert for a potluck event (cake)制作便餐活动的甜点(蛋糕)

Each one of these requires a different set of cooking techniques. Some are unique to an individual context, while others are more generalized. I will explain more in a minute.

这些中的每一个都需要一套不同的烹饪技术。 有些是个别情况所独有的,而另一些则更为笼统。 我将在一分钟内解释更多。

In this case, each cooking context is kind of like an object. If you say that you are going to be cooking out on the grill, for example, that implies that you have a few skills… like operating a grill!

在这种情况下,每个烹饪环境都像一个对象。 例如,如果您说要在烤架上做饭,那意味着您有一些技能……例如操作烤架!

So, if we have an individual method for each of the cooking techniques you might use, there will be some unique methods to each object, and some cases where a method can be applied to multiple objects.

因此,如果我们针对您可能使用的每种烹饪技术都有单独的方法,则每个对象都会有一些独特的方法,并且在某些情况下,一种方法可以应用于多个对象。

In the code above, boiling water is a generalized skill that can probably be applied in any context.

在上面的代码中,沸水是一种通用技能,可以在任何情况下使用。

Let’s use an example. The grill() method is within the context of the cookout object. That means that if you are holding a cookout, you expect that you will need to call up those grill skills.

让我们举个例子。 grill() 方法位于cookout 对象的上下文中。 这意味着,如果您要进行烧烤,那么您将需要调出那些烧烤技能。

But wait. You don’t forget how to use the grill when the cookout ends! Let’s say that you are your partner want to cook a steak for a fancy dinner, like the fancyDinner object. You still want to be able to borrow that grill() method from the cookout object. That is where apply, call, and bind come in.

可是等等。 当烹饪结束时,您不会忘记如何使用烤架! 假设您是您的伴侣,想像做fancyDinner对象一样,为晚餐做一顿牛排。 您仍然希望能够从cookout对象中借用该grill()方法。 那就是应用,调用和绑定进入的地方。

This relationship between cooking skills (methods) and cooking contexts (objects) will be the main way that I show how to use apply, call, and bind().

烹饪技巧(方法)与烹饪上下文(对象)之间的这种关系将是我展示如何使用apply,call和bind()的主要方式。

In order to understand this tutorial, you are going to need to understand this in JavaScript. Check out my tutorial on JavaScript’s this if you need to review that.

为了理解本教程,您将需要在JavaScript中理解 。 看看我的JavaScript的教程是这个 ,如果你需要审查。

绑定方法简介 (An Introduction to the Bind Method)

Let’s imagine that you are holding a cookout for your son or daughter’s 10th birthday party. You want to cook three types of meat on the grill to satisfy everyone: chicken, burgers, and steak. They are apparently all meat eaters at this party.

假设您正在为儿子或女儿的10岁生日聚会举行野餐。 您想要在烤架上烹饪三种肉类以满足所有人的需求:鸡肉,汉堡和牛排。 他们显然是这个聚会上所有的肉食者。

However, you have no idea what each individual person wants! So you are going to need to ask each attendee when they arrive at the party. Each type of meat generally requires the same steps:

但是,您不知道每个人想要什么! 因此,您将需要询问每个与会者何时到达聚会。 每种肉类通常需要相同的步骤:

  1. Add seasoning添加调味料
  2. Put it on the grill放在烤架上
  3. Remove from grill after a certain amount of time一定时间后从烤架上移开

So there is no point in writing a separate method for each type of meat. The only thing that varies is the cooking time. Burgers take 15 minutes, chicken takes 20 minutes, and steak takes 10 minutes.

因此,没有必要为每种肉类编写单独的方法。 唯一不同的是烹饪时间。 汉堡花15分钟,鸡肉花20分钟,牛排花10分钟。

We want to use the same general process for all of these types of meat. The details will vary.

我们希望对所有这些类型的肉使用相同的一般过程。 细节会有所不同。

You may think, “Oh, this is a great time for a function!” But it is a little more complicated than that. As we said above, we are trying to use the concept of execution context to show our cooking skills. You wouldn’t want to cook burgers, chicken, and steak for the first time for an entire party. So, we must represent the skills you have gained over years of cooking, and how you will be applying them to this one particular scenario.

您可能会想:“哦,这是个功能丰富的时光!” 但这要复杂得多。 如上所述,我们正在尝试使用执行上下文的概念来展示我们的烹饪技能。 您不想在整个聚会中第一次煮汉堡,鸡肉和牛排。 因此,我们必须代表您经过多年烹饪获得的技能,以及如何将其应用于这一特定场景。

In this case, our grill method just logs a sentence about when the individual person’s food will be ready. We are going to use bind() to store an execution context. To be clear, the execution context will have two important details.

在这种情况下,我们的烧烤方法仅记录有关何时准备好个人食物的句子。 我们将使用bind()存储执行上下文 。 需要明确的是,执行上下文将有两个重要的细节。

  1. A reference to the cookout object to make sure we use the correct object

    Cookout对象的引用,以确保我们使用正确的对象

  2. The number of minutes of cooking烹饪分钟数

This represents our existing knowledge about how to cook the different types of meat. In each case, we are storing the object and the number of minutes, so we can quickly handle the requests from all the party attendees.

这代表了我们有关如何烹饪不同类型肉类的现有知识。 在每种情况下,我们都存储对象和分钟数,因此我们可以快速处理所有聚会参与者的请求。

Each variable — cookBurger, cookChicken, and cookSteak — is a new function that can be executed at any time with one more argument: the person’s name. So here are three people and their food requests:

每个变量cookBurger,cookChicken和cookSteak是一个新函数,可以随时使用另一个参数(人的名字)执行。 所以这是三个人及其食物要求:

  1. Jack wants a burger杰克想要一个汉堡
  2. Jill wants steak吉尔想要牛排
  3. David wants chicken大卫想要鸡

By using our new functions, we can quickly take these requests without rewriting the grill method. Each of the examples below takes the final argument that is needed for the function to execute in the context of the cookout object.

通过使用我们的新功能,我们可以快速处理这些请求,而无需重写grill方法。 下面的每个示例均采用函数在Cookout对象的上下文中执行所需的最终参数。

Imagine if you were not able to use the bind method here! It would be kind of like you were cooking burgers, chicken, and steak for the first time when the party started. You would be feeding in three arguments to a general grill() method, with no previous planning.

想象一下,如果您在这里不能使用bind方法! 派对开始时,您就像第一次在煮汉堡,鸡肉和牛排。 您将为常规的grill()方法提供三个参数,而无需事先计划。

Instead, we use partial function application to show that we know how to cook each type of meat. We just need to hear what each individual guest wants to eat. This split represents your actual cooking experience.

取而代之的是,我们使用部分功能应用程序来表明我们知道如何烹饪每种类型的肉。 我们只需要听听每个客人想要吃什么。 此拆分代表您的实际烹饪经验。

调用方法简介 (An Introduction To The Call Method)

Here’s another scenario. Let’s say that when you and your partner cook a fancy dinner, you usually like to make some sort of fish and wine. As you can see from the first code snippet, you usually like to cook the fish in the oven.

这是另一种情况。 假设当您和您的伴侣烹饪精美的晚餐时,您通常会喜欢做些鱼和酒。 从第一个代码段可以看到,您通常喜欢在烤箱中煮鱼。

But, you decide that one night, you would like to make steak instead. You are going to need to use the grill to make that steak, obviously.

但是,您决定在某个晚上,您想改做牛排。 显然,您将需要使用烧烤炉来制作牛排。

Here’s the issue: your grill() method is within the context of the cookout object! But now, you want to use those cooking skills within the fancyDinner object. Remember, you don’t want to rewrite the grill method — that will make your code harder to maintain.

这就是问题所在:您的grill() 方法在cookout 对象的上下文中! 但是现在,您想在fancyDinner对象中使用这些烹饪技巧。 请记住, 您不想重写Grill方法-这会使您的代码难以维护。

Instead, you can use JavaScript’s call() method to call the grill method within the context of the fancyDinner object. By using this new context, you will not need to rewrite it. Here is the full code before we get into the details.

相反,您可以使用JavaScript的call()方法在fancyDinner对象的上下文中调用grill方法。 通过使用此新上下文,您将不需要重写它。 这是完整的代码,在我们进入细节之前。

So, our default drink for cookouts is soda, and the default drink for fancy dinners is wine. Now, we just need to add the unusual part as an argument in the call() method — “steak.” Here is the difference between using the method normally, and using call().

因此,我们在户外野餐时默认的饮料是苏打水,在豪华晚宴上的默认饮料是酒。 现在,我们只需要在call()方法中将不寻常的部分作为参数添加到“牛排”即可。 这是通常使用方法和使用call()之间的区别。

The first example should be pretty straightforward: it is all in the context of the cookout object. But in the second example, the first argument changed the context of this to the fancyDinner object!

第一个示例应该非常简单:这一切都在Cookout对象的上下文中进行。 但在第二个例子中,第一个参数改变这样的背景下于fancyDinner对象!

When you get to the console.log statement within the grill() method, you can see that it references a single argument, meal, as well as this.drink.

当您到达grill()方法中的console.log语句时,您会看到它引用了一个参数, 饭食以及this.drink。

When you use fancyDinner as the first argument of the call method, that sets the context to the fancyDinner object. Now, you are able to use those grilling skills in another context.

当将fancyDinner用作调用方法的第一个参数时,会将上下文设置为fancyDinner对象。 现在,您可以在其他情况下使用这些烧烤技巧。

Apply方法简介 (An Introduction To the Apply Method)

The apply() method is very similar to call(), except for one important difference. It can accept an array of arguments, instead of declaring individual parameters. That means that you can create a variadic function — that is, a function with any number of arguments. For that reason, it can only accept two parameters: the context, and an array of arguments.

除了一个重要的区别之外,apply()方法与call()非常相似。 它可以接受一个参数数组,而不是声明单个参数。 这意味着您可以创建一个可变参数函数 ,即具有任意数量参数的函数。 因此,它只能接受两个参数:上下文和参数数组。

Let’s return to our original birthday party example. You are holding a cookout for your son or daughter’s 10th birthday party. 12 kids replied and said they were going, but you do not know how many will actually show up. So, you need to be prepared to grill for an unknown number of people.

让我们回到最初的生日聚会示例。 您正在为儿子或女儿的10岁生日聚会做饭。 12个孩子回答说要去,但您不知道实际上会出现多少个孩子。 因此,您需要做好准备迎接未知人数的人。

However, unlike bind(), functions that are called with apply() will be invoked immediately.

但是,与bind()不同,使用apply()调用的函数将立即被调用。

So, we need to create a function that can handle an array of an unknown number of meal orders, and return the full list of food that you will need to put on the grill. We can retain the organizational structure of the array, which helps give us the order that the requests came in.

因此,我们需要创建一个函数,该函数可以处理未知数量的餐单数组,并返回需要放在烤架上的食物的完整列表。 我们可以保留数组的组织结构,这有助于确定请求的顺序。

There are a couple important things to note here. First of all, notice that the grill method does not have any parameters. This is different than in the past! To resolve this, we use the arguments object in line 4. The arguments object in JavaScript gives us an array-like object full of the arguments of the function.

这里有几件事要注意。 首先,请注意,烤架方法没有任何参数。 这与过去不同! 为了解决这个问题,我们在第4行中使用arguments对象。JavaScript中的arguments对象为我们提供了一个类似数组的对象,其中包含了函数的所有参数。

To convert it to an actual array, we must use the slice() method from the array prototype. This is another handy application of the call() method, since the slice() method is not native to objects.

要将其转换为实际的数组,我们必须使用数组原型中的slice()方法。 这是call()方法的另一个便捷应用,因为slice()方法不是对象固有的。

Finally, we must invoke the function using apply() in order to access the array in the mealOrders property. Here is how to do that.

最后,我们必须使用apply()调用该函数,以便访问餐订单属性中的数组。 这是这样做的方法。

We still must use cookout as the first argument, because just like call(), we must declare the execution context. Then, we can feed in the array from the mealOrders property.

我们仍然必须使用cookout作为第一个参数,因为就像call()一样,我们必须声明执行上下文。 然后,我们可以从mealOrders属性中输入数组。

This allows us to use an indefinite number of elements within the grill() method since we can pass in an array as the second argument.

这允许我们在grill()方法中使用无限数量的元素,因为我们可以传入数组作为第二个参数。

获取最新教程 (Get The Latest Tutorials)

Did you enjoy this tutorial? Give it a clap so others can find it too. Or, sign up to get my latest visualized tutorials from the CodeAnalogies blog here:

您喜欢本教程吗? 给它鼓掌,以便其他人也可以找到它。 或者,在此处注册以从CodeAnalogies博客获取我的最新可视化教程:

翻译自: https://www.freecodecamp.org/news/javascripts-apply-call-and-bind-explained-by-hosting-a-cookout-84b85977ee11/

javascript晚绑定

javascript晚绑定_JavaScript的应用,调用和绑定通过托管野餐来解释相关推荐

  1. 使用基于 WebRTC 的 JavaScript API 在浏览器环境里调用本机摄像头

    HTML5,JavaScript 和现代浏览器这套三驾马车的组合,使得传统的 Web 应用较之过去能实现更多更丰富的同用户交互的功能.摄像头如今已成为智能手机的标配,前端 Web 应用也出现了越来越多 ...

  2. [C++11]可调用对象绑定器

    std::bind用来将可调用对象与其参数一起进行绑定.绑定后的结果可以使用std::function进行保存,并延迟调用到任何我们需要的时候.通俗来说,它主要有两个作用: 1.将可调用对象与其参数一 ...

  3. Python 绑定:从 Python 调用 C 或 C++

    摘要:您是拥有想要从 Python 中使用的C或 C++ 库的 Python 开发人员吗?如果是这样,那么Python 绑定允许您调用函数并将数据从 Python 传递到C或C++,让您利用这两种语言 ...

  4. Vue的数据绑定、Vue的事件绑定、Class和Style的绑定

    一.Vue的数据绑定 1. 单向数据绑定:将Model绑定到View上,当通过JavaScript代码改变了Model时,View就会自动刷新.不需要进行额外的DOM操作就可以实现视图和模型的联动 ​ ...

  5. 二、Vue 属性绑定、v-model的原理、绑定class、绑定style

    一.属性绑定和v-model的原理 v-bind: 可以绑定属性 例如 value属性 class属性 style属性等 也可以直接简写成 : <!DOCTYPE html> <ht ...

  6. vue.js的一些事件绑定和表单数据双向绑定

    知识点: v-on:相当于: 例如:v-on:click==@click ,menthods事件绑定 v-on修饰符可以指定键盘事件v-model进行表单数据的双向绑定 <template> ...

  7. 组件间的双向绑定、如何自己定制双向绑定

    1.组件间的双向绑定 1.1 组件的双向绑定的介绍 由于vue中的单项数据流,一般来说,父组件通过自定义属性传输数据,子组件通过props字段接受数据,如果子组件想要更改父组件传过来的数据,可以通过t ...

  8. oracle 新建绑定变量,在Oracle中,绑定变量是什么?绑定变量有什么优缺点?

    ♣答案部分 绑定变量这节的内容较多,下面给出这节涉及到的关系图: (一)绑定变量的含义及优缺点 通常在高并发的OLTP系统中,可能会出现这样的现象,单个SQL的写法.执行计划.性能都是没问题的,但整个 ...

  9. JavaScript基础14-day16【事件委派、事件绑定、事件传播、滚轮事件、键盘事件、键盘移动div】

    学习地址: 谷粒学院--尚硅谷 哔哩哔哩网站--尚硅谷最新版JavaScript基础全套教程完整版(140集实战教学,JS从入门到精通) JavaScript基础.高级学习笔记汇总表[尚硅谷最新版Ja ...

最新文章

  1. Java方法调用事件_Java中的事件处理和Java中actionPerformed方法的执行
  2. Oracle 11g R2 RAC 高可用连接特性
  3. [Python图像处理] 十三.基于灰度三维图的图像顶帽运算和黑帽运算
  4. phalcon: 缓存片段,文件缓存,memcache缓存
  5. C++ 内建函数对象
  6. Atcoder ARC101 E 树dp
  7. Mac OS 如何更改文件的默认打开方式
  8. AFNetworking网络请求与图片上传工具(POST)
  9. 指纹识别 python_python 网站指纹识别
  10. JavaScript数组拼接、对象拼接
  11. Canvas学习:封装Canvas绘制基本图形API
  12. Rabbit MQ 配置
  13. cookie 和 session 区别
  14. MySQL一主二从复制环境切换主从库
  15. Bluebird-Collections
  16. 正在启动文档服务器,正在启动远程服务器
  17. MySQL-在字段上使用函数不会走索引的原因是什么?
  18. 机械革命bios升级_旧笔记本光驱换SSD,升级内存,改造散热还能再战5年
  19. 整理:周鸿祎谈如何写商业计划书
  20. tkmybatis 枚举值处理

热门文章

  1. Window对象中setInterval()和setTimeout()的区别
  2. php删除指定对象的属性及属性值
  3. [译] iOS 开发之新版 APNs 搭建必备知识
  4. mariadb 内存占用优化
  5. ABP理论学习之数据传输对象(DTO)
  6. 使用VB.NET加快代码开发速度
  7. angularJs的学习笔记-01(创建项目)
  8. oracle11g数据库升级
  9. wifidog接口文档(转)
  10. 超大磁盘分区工具parted使用介绍(一)