1. 全局执行
1). 浏览器:
window
2). node:
global
2. 函数调用
1). 纯粹的全局函数调用
window
2). 严格模式: ‘use strict’
undefined
3.作为对象的方法调用
当一个函数被当作一个对象的方法调用的时候:
1 | function test() { |
函数仅仅是一个指针而已,调用的时候上下文仍然算obj的。而如果是直接给一个全局变量:
1 | var name = "Messi"; |
调用的test,而test是一个全局变量,因此this指向全局下的name。
特例
1 | var obj = { |
因为事件机制的问题,setTimeout会稍后执行,然后指向的是window,在定时器内部的匿名函数中以this.foo为参数,但是与obj是没有关系的,指向window,最终只会输出123,不会执行定时器的函数。可以将setTimeout外的this对象存起来之后,传递给里面的函数,而这就需要闭包的特性来解决。
1 | foo2: function() { |
隐式绑定this
即使在严格模式下,setTimeout方法在调用传入函数的时候,如果这个函数没有指定了的 this,那么它会做一个隐式的操作,自动地注入全局上下文,等同于调用 foo.apply(window)而非foo();
1 | ; |
4. 作为构造函数使用
new操作符干的事,不再赘述,最后this指向的是实例对象
5. 箭头函数(Arrow function)
继承了外围作用域的this对象,并且在词法作用域阶段就已经决定好了,call/apply/bind都无法改变
6. call,apply,bind
说一个特例:在构造函数中如果用bind改变this,并不会生效。
1 | function Person(name){ |
可以看到,new实例并没有改变指向为obj,this仍然指向的是person。但是传入的参数”Messi”确实生效了。