普通函数 判断 this 绑定,依据4条规则。并根据它们的优先级判断函数在某个调用位置应用的是哪条规则,顺序如下:
-
函数是否在 new 中调用(new绑定)?如果是,this 绑定的是新创建的对象
// foo 函数中的 this 绑定 bar var bar = new foo()
-
函数是否通过 call、apply(显示绑定)或者 bind (硬绑定)调用?如果是,this 绑定的是指定的对象
// foo 函数中的 this 绑定 obj2 var bar = foo.call(obj2)
-
函数是否在某个上下文对象中调用(隐式绑定)?如果是,this 绑定的是这个上下文对象
// foo 函数中的 this 绑定 obj1 var bar = obj1.foo() // 链式对象会绑定最终的对象:下面的 this 会绑定 obj1.obj2.obj3,而不是 obj1 var baz = obj1.obj2.obj3.foo()
-
如果都不是的话,使用默认绑定。如果在严格模式下,就绑定到 undefined,否则绑定到全局对象
// 非严格模式下,浏览器环境绑定 window var bar = foo()
简洁版:
- 由 new 调用?绑定到新创建的对象
- 由 call 或者 apply (或者 bind)调用?绑定到指定的对象
- 由上下文对象调用?绑定到这个上下文对象
- 默认:在严格模式下绑定到 undefined,否则绑定到全局对象
ES6 中的箭头函数并不会使用四条标准的绑定规则,而是更具当前的词法作用域决定this。
具体来说,箭头函数会继承外层函数调用的 this 绑定(无论 this 绑定到什么)。
这其实和 ES6 之前代码中的 self = this
机制一样。
更多详情请查看**《你不知道的JavaScript》 - 第2章 this全面解析**