针对this指向问题,有很多种理解方式. 今天,就针对`JavaScript语言精粹(修订版)`给大家介绍一下函数调用中this的指向问题.
调用一个函数会暂停当前函数的执行,传递控制权和参数给新函数.除了声明时定义的形式参数,每个函数还接收两个附加的参数:`this`和`arguments`.参数`this`在面向对象编程中非常重要,它的值取决于**调用的模式**.在JavaScript中一共有4中调用模式:**方法调用**、**函数调用**、**构造器调用**、**apply调用模式**。
# 方法调用模式
---
方法定义:当一个函数被保存为对象的一个属性时,我们称它为一个方法。
定义:当一个方法被调用时,`this`被绑定到改对象.如果调用表达式包含一个提取属性的动作(即包含一个`.点表达式`或`[subscript]下标表达式`),那么它就被当做一个方法来调用.
```
var myObject = {
value: 0,
increment: function(inc){
this.value += typeof inc === 'number' ? inc : 1;
}
};
myObject.increment();
console.log(myObject.value); // 1
myObject.increment(2);
console.log(myObject.value); // 3
```
# 函数调用模式
---
当一个函数并非一个对象的属性时,那么它就是被当做一个函数来调用的:
```
var sum = add(3, 4); // sum的值为7
```
以此模式调用函数时,this被绑定到全局对象.
```
// 给myObject增加一个double方法
myObject.increment = function() {
var that = this // 解决方法
var helper = function () {
that.value = that.value + that.value
}
helper(); // 以函数形式调用helper
}
myObject.double();
console.log(myObject.value) // 6
```
# 构造器调用模式
---
> 构造器函数定义: 一个函数,如果创建的目的就是希望结合`new`前缀来调用,那它就被称为`构造器函数`
如果一个函数前面带上了`new`来调用,那么背地里将会创建一个连接到该函数的`prototype`成员的新对象,同时`this`会被绑定到那个新对象上.
# apply/call调用模式
---
`apply`/`call`作用一样,允许我们选择`this`的值.
`apply`方法接收两个参数,第一个参数是要绑定`this`的值,第二个参数是一个数组.
`call`与`apply`不同的是 call有多个参数,除第一个参数是绑定this之外,其余参数均是带入到函数中的参数.
【JavaScript语言精粹(修订版)】函数调用中的this指向问题