执行上下文的生命周期:
this的指向,是在函数被调用的时候确定的。即执行上下文被创建时确定的。
在函数执行过程中,this一旦被确定,就不可更改了。
全局对象中的this
全局对象的this指向它本身。
函数中的this
在一个函数上下文中,this由调用者提供,由调用函数的方式来决定。
如果调用者函数,被某一个对象所拥有,那么该函数在调用时,内部的this指向该对象。如果函数独立调用,那么该函数内部的this,则指向undefined。
但是在非严格模式中,当this指向undefined时,它会被自动指向全局对象。
当obj在全局声明时,无论obj.c在什么地方调用,这里的this都指向全局对象,而当obj在函数环境中声明时,这个this指向undefined,在非严格模式下,会自动转向全局对象。
使用call,apply显示指定this
fn并非属于对象obj的方法,但是通过call,我们将fn内部的this绑定为obj,因此就可以使用this.a访问obj的a属性了。
而call与applay后面的参数,都是向将要执行的函数传递参数。其中call以一个一个的形式传递,apply以数组的形式传递。这是他们唯一的不同。
function fn(num1, num2) {
console.log(this.a + num1 + num2);
}
var obj = {
a: 20
}
fn.call(obj, 100, 10); // 130
fn.apply(obj, [20, 10]); // 50
call/apply拥有了很多有用处的场景:
- 将类数组对象转换为数组
- 根据自己的需要灵活修改this指向
- 实现继承
- 在向其他执行上下文的传递中,确保this的指向保持不变
构造函数与原型方法上的this
通过new操作符调用构造函数,会经历以下4个阶段。
- 创建一个新的对象;
- 将构造函数的this指向这个新对象;
- 指向构造函数的代码,为这个对象添加属性,方法等;
- 返回新对象。
当new操作符调用构造函数时,this其实指向的是这个新创建的对象,最后又将新的对象返回出来,被实例对象接收。因此,这个时候构造函数的this指向了新的实例对象。