译者:江吉仪
回顾一下“this”
在面向对象的 js中,万物皆对象,因为万物皆对象,我们可以为函数设置和访问额外的属性。
给函数设置额外属性和给函数添加方法是很好...但是我们怎么访问这些属性和方法???
我们介绍过 this 关键字。我们知道到每个函数都会自动获得 this 这个属性。如果我们要为这个函数执行上下文创建一个抽象模型(我不是唯一个这样子做的人...对吧?!?!),他会像这样子的:

我们会花了一点时间来熟悉this关键字,但当我们了解this用处,我们会意识到它是多么有用了。this是在函数内部使用的,并且总是引用某个对象——这个对象会在使用“this”的地方调用函数。
但事情肯定永远是不完美的,有时候我们会失去this 的指向。当这个事情发生时,我们最后会迷惑的方式保存this 的指向,查看具体例子。

为什么要保存 this 的指向?因为deleteBtn.addEventListener的 this 指向的deleteBtn对象。 这样子不太好,我们有更好的的办法吗?
###call(),apply()和 bind() - 新的希望
到现在为止,我们把函数当做一个由名字(同样可以是一个匿名函数)和其调用时执行代码组成的对象,但这不是全部的真相,作为一个热爱真理的人,我有必要让你知道函数实际上看起来是下面这样子的:

这是啥? 别担心!我会通过三个相似的方法添加到函数上面,通过例子让你明白。
bind()
bind()的官方文档:bind()方法创建了一个新的函数,当他被调用时,新函数 this 关键字设置为传递第一个参数(实际上有很多东西可以展开,但时间原因下一次再聊)
这是很强大的,让我们在调用的时候明确的定义 this 的值 ,让我们看下代码:
var pokemon = {
fistname : 'Pika',
lastname: 'Chu',
getPokeName: function() {
var fullname = this.fistname + '' + this.lastname;
return fullname;
}
var pokemonName = function () {
console.log(this.getPokeName()+ 'i choose you ')
}
var logPokemon = pokemonName.bing(pokemon); }
在第 14 行使用 bind 方法。
让我们分解一下代码,当我们使用 bind()方法:
1 js 引擎会创建一个新的 pokemonName 实例,然后绑定 pokemon 作为他的 this 的变量。最重要的是理解它复制 pokemonName 函数了。
2.在创建了 pokemonName 函数副本后,让他去调用 logPokemon()。 尽管它最初不是在 pokemon 对象上面。但现在它将要识别属性(Pika 和Chu)和方法
最棒的事情是,在我们绑定了一个值之后,我们可以像使用普通函数一样使用它,我们甚至可以让函数接受参数,然后传递:
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()方法。可以把我们从垃圾代码中解放出来。
bind 和 call 方法的区别是call 方法:
1.可以接受别的参数。
2立即执行调用它的函数。
3call 方法不会复制正在调用它的函数。
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
这些内置在函数的方法,每一个都是非常有用的。即使你不在平常写代码中使用,但是当你读别人的代码时候还是会经常遇到。
如果你有任何问题,来 Instagram找我。