- 原文地址:Javascript: call(), apply() and bind()
- 原文做者:Omer Goldberg
- 译文出自:掘金翻译计划
- 本文永久连接:github.com/xitu/gold-m…
- 译者:YueYong
- 校对者:Guangping, sun
咱们了解到,在面向对象的 JS 中,一切都是对象。由于一切都是对象,咱们开始明白咱们能够为函数设置并访问额外的属性。javascript
经过原型给函数设置属性而且添加其余方法很是棒...可是咱们如何访问它们?!???!前端
当他说 “myself” 时,他的确意味着 ‘this’java
咱们介绍过 this
关键字。咱们了解到每一个函数都会自动获取此属性。因此这时,若是咱们建立一个有关咱们函数执行上下文的抽象模型(我不是惟一一个这么作的人!...对吗?!?!),它看起来就会像这样:android
咱们花了一些时间来熟悉 this
关键字,可是一旦咱们这样作了,咱们就开始意识到它是多么有用了。this
在函数内部使用,而且老是引用单个对象 — 这个对象会在使用 “this” 的地方调用函数。ios
可是生活确定都不是完美的。有时候咱们会失去 this
的引用。当这种状况发生时,咱们最终使用了使人困惑的解决方法去保存咱们对于 this
的引用。让咱们经过 localSorage 练习来看看这个方法吧:git
第 31 行 :(github
那为何我须要保存 this
引用呢?由于在 deleteBtn.addEventListener 中,this
指向了 deleteBtn 对象。这并不太好。有更好的解决方案吗?编程
到目前为止,咱们已将函数视为由名称(可选,也能够是匿名函数)及其在调用时执行的代码所组成的对象。但这并非所有真相。做为一个 热爱真理的人,我必须让你知道一个函数实际上看起来更接近下面的图像:后端
这是什么???????别担忧!如今,我将经过示例介绍每一个函数中出现的这 3 种相似方法。真是很让人兴奋呢!数组
官方文档说: 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()
方法:
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() 方法的官方文档说: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、前端、后端、区块链、产品、设计、人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划、官方微博、知乎专栏。