参考
阮一峰老师对于this的原理理解
一:this的定义
在严格模式下和非严格模式下,this的在全局中会有差别
来自阮一峰老师对于this的由来的理解
由于函数可以在不同的运行环境中运行,所以需要一种机制,能够在函数的内部获取当前运行环境,因此this就出现来,
this的设计目的就是为了在函数的内部,指代函数当前的运行环境
所以在绝大多数的情况下,函数当前的运行环境决定了this的值
例如:
1 | var obj = { |
- 对于
obj.foo()来说,是通过obj这个对象来找到foo(),所以foo()的运行环境obj对象,因此this的值就是Obj对象 - 对于
foo()来说,foo()函数的运行环境是window,因此this的值就是window 
二:绑定规则
根据不同的使用场合,this有不同的值,主要分为下面几种情况:
- 默认绑定
- 隐式绑定
- new绑定
- 显示绑定
1. 默认绑定
默认绑定的意思就是,当函数独立执行,不作为一个对象的方法调用时,
this绑定到全局对象中,但在严格模式下,this会绑定到undefined
1 | function foo () |
2. 隐式绑定
当函数作为对象的方法调用时,
this绑定到调用该方法的对象
1 | var obj = { |
这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象
1 | var obj = { |
foo执行的环境是a对象,所以this指向a对象

再例如:
1 | var obj = { |
在该代码中,定义了一个变量
fn,被将其赋值为obj.a.foo,这意味着fn现在引用了,obj对象中,a属性的foo方法。最后调用
fn(),执行foo()函数将
obj.a.foo复制给fn,只是将foo函数的引用复制给了fn,但并没有立即执行。所以fn只是函数的引用,它的上下文还是跟obj.a.foo相关但是当调用
fn()时,这才是真正执行foo函数的时候,但由于fn是在全局上下文中调用的,JS将函数上下文this赋值为window
3. 显示绑定
使用
call()、apply()或bind()方法显式地指定函数的this值。
1 | var obj = { |

4. new 绑定
当函数用作构造函数(使用
new关键字创建对象)时,this绑定到新创建的对象。
1 | function fn () |
- 通过
new关键字改变了this的执行,指向了obj
当函数返回一个对象
1 | function fn () |
- 当函数返回一个对象时,通过new关键字将this指向改变指向返回的对象,不指向obj
当返回一些简单类型时候
1 | function fn () |
- this还是指向obj
返回null
1 | function fn () |
- 虽然null是object类型
- 但是还是指向obj
三:箭头函数
JS中箭头函数与普通函数在
this上有着重要的不同。箭头函数
this的绑定是在箭头函数创建的时候就确定的好的,是静态this绑定,它没有自己的上下文,它会捕获最近的普通函数的this值普通函数
this值取决于,函数是如何被调用的,是根据调用方式动态确定的
在全局上下文中
1 | var a = 1 |

fn箭头函数会自动捕获最近的最近的普通函数上下文,通常是全局对象window
在对象方法中
1 | var a = 10 |

fn箭头函数的this值不取决于被调用时动态绑定,而是在静态创建时候,与最近最近的普通函数上下文this值一致fn箭头函数最近最近的普通函数上下文是window全局- 因此
this指向window
作为事件回调
1 | <button id="btn">点击</button> |
1 |
|
- 点击按钮输出还是10
- 箭头函数作为回调函数时,其
this绑定通常与定义它的上下文相同。
四:优先级
1. 隐式绑定 VS 显示绑定
1 | function foo() { |
- 显示绑定优先级要高于隐式绑定
2. new绑定 VS 显示绑定
1 | function Person(name) { |
new绑定的优先级更高。当使用new关键字创建对象实例时,它会覆盖之前的显式绑定
