确定 this 指向
this
的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this
到底指向谁,实际上this
的最终指向的是那个调用它的对象。
全局上下文
- 浏览器环境,严格模式或非严格模式
this
指向Window
对象。
1 | <script> |
- node 环境,指定
空对象{}
1 | console.log("this", this);//window |
函数上下文
普通函数
- 浏览器环境,非严格模式,
this
指向window
;
1 | <script> |
- 浏览器环境,严格模式,
this
指向undefined
1 | function a() { |
- node 环境,
this
指向global
1 | function foo() { |
箭头函数
- 浏览器环境
箭头函数中没有this
绑定,必须通过查找作用域链来决定其值。 如果箭头函数被非箭头函数包含,则this
绑定的是最近一层非箭头函数的this
,否则this
的值则被设置为全局对象。
1 | <script> |
node
环境
与浏览器环境一样
1 | function a() { |
对象的方法
如果函数作为对象的方法调用,this
指向的是这个上级对象,即调用方法的对象。
1 | let name = 'window'; |
call 方法执行函数,传入的第一个参数就是 this 的指向
如果将对象方法赋值给变量就变成了普通函数
1 | let student = { |
构造函数中的 this
构造函数使用 new 调用的时候,如果没有返回 function 或者是 object,this 指向当前的实例。
1 | function showName(name) { |
call、apply 和 bind
this 是第一个参数,bind 不会执行,返回绑定好的函数。apply 的第二个参数是数组。
- 如果第一个参数值是
undefined
或null
,严格模式下this
的值为传入的值null
或undefined
,非严格模式下,this
指向全局对象(node 环境为 global,浏览器环境为 window)。 - 如果第一个参数没有传入,非严格模式,指向
window/global
,严格模式指向undefined
1 | function add(c, d) { |
- 如果第一个参数值为原始值(数字,字符串,布尔值)的
this
会指向该原始值的自动包装对象。
1 | var doSth = function (name) { |
事件处理函数
在严格模式下,在事件处理函数中,this 指向触发事件的目标对象。
1 | "use strict"; |
总结
如果要判断一个运行中函数的 this 绑定, 就需要找到这个函数的直接调用位置。 找到之后
就可以顺序应用下面这四条规则来判断 this 的绑定对象。
- new 调用:绑定到新创建的对象,注意:显示 return 函数或对象,返回值不是新创建的对象,而是显式返回的函数或对象。
- call 或者 apply( 或者 bind) 调用:严格模式下,绑定到指定的第一个参数。非严格模式下,null 和 undefined,指向全局对象(浏览器中是 window),其余值指向被 new Object()包装的对象。
- 对象上的函数调用:绑定到那个对象。
- 普通函数调用: 在严格模式下绑定到 undefined,否则绑定到全局对象。