【译】Javascript: call()、apply() 和 bind()
栏目: JavaScript · 发布时间: 7年前
内容简介:我们了解到,在面向对象的 JS 中,一切都是对象。因为一切都是对象,我们开始明白我们可以为函数设置并访问额外的属性。通过原型给函数设置属性并且添加其他方法非常棒...当他说 “myself” 时,他的确意味着 ‘this’
我们了解到,在面向对象的 JS 中,一切都是对象。因为一切都是对象,我们开始明白我们可以为函数设置并访问额外的属性。
通过原型给函数设置属性并且添加其他方法非常棒... 但是我们如何访问它们?!???!
当他说 “myself” 时,他的确意味着 ‘this’
我们介绍过 this 关键字。我们了解到每个函数都会自动获取此属性。所以这时,如果我们创建一个有关我们函数执行上下文的抽象模型(我不是唯一一个这么做的人!...对吗?!?!),它看起来就会像这样:
我们花了一些时间来熟悉 this 关键字,但是一旦我们这样做了,我们就开始意识到它是多么有用了。 this 在函数内部使用,并且总是引用单个对象 — 这个对象会在使用 “this” 的地方调用函数 。
但是生活肯定都不是完美的。有时候我们会失去 this 的引用。当这种情况发生时,我们最终使用了令人困惑的解决方法去保存我们对于 this 的引用。让我们通过 localSorage 练习 来看看这个方法吧:
第 31 行 :(
那为什么我需要保存 this 引用呢?因为在 deleteBtn.addEventListener 中, this 指向了 deleteBtn 对象。这并不太好。有更好的解决方案吗?
call()、apply() 和 bind() — 一个新的希望
到目前为止,我们已将函数视为由名称(可选,也可以是匿名函数)及其在调用时执行的代码所组成的对象。但这并不是全部真相。作为一个 热爱真理的人,我必须让你知道一个函数实际上看起来更接近下面的图像:
这是什么???????别担心!现在,我将通过示例介绍每个函数中出现的这 3 种类似方法。真是很让人兴奋呢!
bind()
官方文档说: bind() 方法创建一个新函数,在调用时,将其 this 关键字设置为所需的值。(它实际上谈论了更多的东西,但我们将把它留到下一次讲)
这非常强大。它让我们在调用函数时明确定义 this 的值。我们来看看 cooooode:
var pokemon = {
firstname: 'Pika',
lastname: 'Chu ',
getPokeName: function() {
var fullname = this.firstname + ' ' + this.lastname;
return fullname;
}
};
var pokemonName = function() {
console.log(this.getPokeName() + 'I choose you!');
};
var logPokemon = pokemonName.bind(pokemon); // creates new object and binds pokemon. 'this' of pokemon === pokemon now
logPokemon(); // 'Pika Chu I choose you!'
复制代码
在第 14 行使用了 bind()方法 。
我们来逐个分析。当我们使用了 bind() 方法:
- JS 引擎创建了一个新的
pokemonName的实例,并将pokemon绑定到this变量。 重要的是要理解 它复制了 pokemonName 函数。 - 在创建了
pokemonName函数的副本之后,它可以调用logPokemon()方法,尽管它最初不在pokemon对象上。它现在将识别其属性(Pika 和 Chu)及其方法。
很酷的是,在我们 bind() 一个值后,我们可以像使用任何其他正常函数一样使用该函数。我们甚至可以更新函数来接受参数,并像这样传递它们:
var pokemon = {
firstname: 'Pika',
lastname: 'Chu ',
getPokeName: function() {
var fullname = this.firstname + ' ' + this.lastname;
return fullname;
}
};
var pokemonName = function(snack, hobby) {
console.log(this.getPokeName() + 'I choose you!');
console.log(this.getPokeName() + ' loves ' + snack + ' and ' + hobby);
};
var logPokemon = pokemonName.bind(pokemon); // creates new object and binds pokemon. 'this' of pokemon === pokemon now
logPokemon('sushi', 'algorithms'); // Pika Chu loves sushi and algorithms
复制代码
call(), apply()
call() 方法的官方文档说: call() 方法调用一个给定 this 值的函数,并单独提供参数。
这意味着,我们可以调用任何函数,并明确指定 this 应该在调用函数中引用的内容。真的类似于 bind() 方法!这绝对可以让我们免于编写 hacky 代码(即使我们仍然是 hackerzzz)。
bind() 和 call() 之间的主要区别在于 call() 方法:
call()
call() 和 apply() 使用于 完全相同的目的。 它们工作方式之间的唯一区别 是 call() 期望所有参数都单独传递,而 apply() 需要所有参数的数组。例如:
var pokemon = {
firstname: 'Pika',
lastname: 'Chu ',
getPokeName: function() {
var fullname = this.firstname + ' ' + this.lastname;
return fullname;
}
};
var pokemonName = function(snack, hobby) {
console.log(this.getPokeName() + ' loves ' + snack + ' and ' + hobby);
};
pokemonName.call(pokemon,'sushi', 'algorithms'); // Pika Chu loves sushi and algorithms
pokemonName.apply(pokemon,['sushi', 'algorithms']); // Pika Chu loves sushi and algorithms
复制代码
注意,apply 接受数组,call 接受每个单独的参数。
这些存在于每一个 JS 函数的内置方法都非常有用。即使你最终没有在日常编程中使用它们,你仍然会在阅读其他人的代码时经常遇到它们。
如果您有任何疑问,请一如既往地通过Instagram 与我们联系。❤
如果发现译文存在错误或其他需要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可获得相应奖励积分。文章开头的 本文永久链接 即为本文在 GitHub 上的 MarkDown 链接。
掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为掘金 上的英文分享文章。内容覆盖 Android 、 iOS 、 前端 、 后端 、 区块链 、 产品 、 设计 、 人工智能 等领域,想要查看更多优质译文请持续关注 掘金翻译计划 、官方微博、 知乎专栏 。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
写给大家看的设计书(第3版)
[美] Robin Williams / 苏金国、刘亮 / 人民邮电出版社 / 2009-1 / 49.00元
这本书出自一位世界级设计师之手。复杂的设计原理在书中凝炼为亲密性、对齐、重复和对比4 个基本原则。作者以其简洁明快的风格,将优秀设计所必须遵循的这4 个基本原则及其背后的原理通俗易懂地展现在读者面前。本书包含大量的示例,让你了解怎样才能按照自己的方式设计出美观且内容丰富的产品。 此书适用于各行各业需要从事设计工作的读者,也适用于有经验的设计人员。一起来看看 《写给大家看的设计书(第3版)》 这本书的介绍吧!