1. 全局下的 this
在全局环境下,this
指向全局对象。
全局对象和宿主环境相关,在浏览器下,全局对象就是 window
对象,在 node.js
中,全局对象是 global
对象。
- 1
2. 函数中的 this
函数在不同情况下,其 this
的指向也不同。
2.1 对象下的方法
方法也是一个函数,如果通过对象调用一个函数,函数的 this
就会指向这个对象。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
say函数
作为对象下的方法,在被调用后,其 this
指向的是他所在的对象,在这里就是 person
对象。
2.2 原型链上方法的 this
原型链上的方法,this 指向的也是调用该方法的对象。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
Object.create
做就就是将参数作为原型,创建一个对象。
所以 object
的第一原型就是 __proto__
对象。
number1
和 number2
都是 object
变量的属性,但却可以被 sum
方法中的 this
访问到,所以在原型链的方法中,this 指向的就是调用该方法的对象。
2.3 getter / setter 下的 this
getter
和 setter
下的 this 也会指向调用该 getter
和 setter
的对象。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
getter
和 setter
本质上也可以理解成两个函数,作为对象下的函数,在调用的时候 this
也会指向该对象。
2.4 作为 DOM 节点的事件处理器
作为 DOM 节点的事件处理器的时,函数的 this
会指向这个 DOM 对象。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
2.5 作为一个内联的事件处理器
内联的事件处理器,其 this
指向的是 DOM 节点自身。
- 1
- 2
- 3
这个规则有局限性,只有最外层的 this 符合这个规则。
- 1
- 2
- 3
test
函数的 this 指向的是全局对象 window
。
2.6 其他大部分情况下
排开上述的几个情况,剩下的函数大部分情况下在调用时,this 指向的是全局对象,在浏览器中就是 window
对象。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
这样调用函数,其 this 指向的就是 window 对象了。
有的时候可能会搞混以下情况:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
这里 thisTest
方法输出的 username
就会是个 undefined,因为他的 this 指向的是 window,因为他不属于 object
对象的一个方法,所以 this 就指向了 window。
在回调函数中经常会碰到这个问题:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
这里回调函数获取的账号和密码是 undefined
,原因就是 this 的指向问题。
通常会使用保留上层 this 的方式解决这个问题。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
这样就能解决这个问题。
另外一个情况也很容易混淆 this :
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
这是因为把 object
下的 say
方法单独赋值给 say 变量的时候,其就作为了 window 下的一个方法,所以他的 this 指向的是 window。
在严格模式中,这种情况下的 this
会变成 undefined
。
2.7 构造函数
在 JavaScript 构造函数也被成为 对象构造器
,用于产生对象。
构造函数的声明和普通函数几乎没有区别:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
构造函数使用 new
关键字来构造对象。所以当一个函数被使用 new
关键字调用时,这个函数就会作为一个构造函数。
在一个构造函数被调用后,其内部的 this
会指向一个对象,具体的内容可以参考 构造函数
章节。
3. 修改this
3.1 call 方法和 apply 方法
函数具有 call
方法和 apply
方法,这两个方法可以在调用函数的时候指定函数的 this。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
通过 call
和 apply
方法将 say 函数执行时候的 this 设置为 object
对象。
call 方法从第二个参数开始,表示是要传递给当前函数的参数。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
apply 的第二个参数是个数组,数组里面的项会按数组的顺序作为参数传递给函数。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
通过 arguments
关键字就可以看到当前函数的参数,通常在需要修改 this ,又不确定参数的情况下,会使用 apply
来修改 this。
3.2 bind
bind 方法用于给一个函数永久绑定一个指定的 this,bind 不会修改原函数,会返回一个新的函数。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
可以看到 bindFn1
被绑定了 obj1
作为 this,之后不论怎么操作,他的 this 都会是 obj1
。
4. 小结
理解好 this 的处理机制可以设计出更加完善的 JavaScript 应用程序。
this 在 ES6 的箭头函数中的表现也有所不同,可以查阅 ES6 中有关箭头函数的内容。