多数情况下函数的调用方式决定了 this 的值(运行时绑定)。
ES5 使用 bind 方法设置 this 值,使得不用考虑函数如何被调用。
全局上下文
在全局执行上下文下,无论是否是严格模式,this 都指向全局对象。
1 | // 在浏览器中, window 对象同时也是全局对象: |
函数上下文
作为函数调用
在函数内部,this 的值取决于函数被调用的方式。
调用时不设置 this
非严格模式: window
1
2
3
4
5function f1() {
return this;
}
console.log( f1() );// window 对象严格模式: undefined
1
2
3
4
5
6function f2() {
;
return this;
}
console.log( f2() );// undefined
作为方法调用
类上下文
- 类函数中的 this 表示类
- 实例函数中的 this 表示类的原型
- 派生类调用 super() 后才有 this,相当于 this = new Base(),Base 为基类
构造函数
构造函数中的 this 为构造函数的返回值,默认返回值为创建的实例对象,但返回值可以被修改。
1 | function C(){ |
类中的 this
可以通过 bind 将 this 指向实例。
1 | class Car { |
原型链中的 this
当被当做方法调用时,this 被设置为调用该函数的对象。
1 | var o = { |
绑定函数上下文
call
apply
bind
使用 bind 创建的新函数,新函数中的 this 永久绑定到第一个参数,无论新函数什么时候被调用,this 都是使用 bind 时的第一个参数。
1
2
3
4
5
6
7
8
9
10
11
12
13function f(){
return this.a;
}
//新建的函数 g 中, this 值将永久被绑定到第一个参数 {a:"azerty"}
var g = f.bind({a:"azerty"});
console.log(g()); // azerty
var h = g.bind({a:'yoo'}); // bind 只生效一次!
console.log(h()); // azerty
var o = {a:37, f:f, g:g, h:h};
console.log(o.a, o.f(), o.g(), o.h()); // 37, 37, azerty, azerty
DOM 事件处理函数
使用 addEventListener
添加的事件处理函数, this 指向触发事件的元素,即 currentTarget。
1 | // 被调用时,将关联的元素变成蓝色 |
内联事件处理函数
当代码被内联 on-event 处理函数 调用时,它的this
指向监听器所在的DOM元素:
1 | <button onclick="alert(this.tagName.toLowerCase());"> |
下面示例没有设置内部函数的 this
,所以它指向 global/window 对象(因为非严格模式下调用的函数未设置 this
时指向的默认对象)
1 | <button onclick="alert((function(){return this})());"> |
箭头函数
箭头函数中的 this 表示创建时的作用域,而不是运行时的。通过 call apply bind 给箭头函数绑定 this 时,this 会被忽略。
1 | var globalObject = this; |