前言:this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定,this最终指向调用它的对象。

全局作用域或函数调用下

  • 全局作用域或者普通函数中 this 指向全局对象 window。
1
2
3
4
5
6
7
8
9
//直接打印
console.log(this) //window

function A(){
var a = 'HelloWorld'
console.log(this.a) // undefined
console.log(this) // window
}
A()

方法调用下

  • 方法调用中谁调用了,this 指向谁
  • 当函数被保存为一个对象的属性时,它就可称为这个对象的方法。当一个方法被调用时,this被绑定到这个对象上
1
2
3
4
5
6
7
var A = {
a : 'Hi',
sayHi : function(){
console.log(this.a) // Hi
}
}
A.sayHi()
  • 因为是A.b调用的这个函数,所以指向b这个对象
1
2
3
4
5
6
7
8
9
10
11
12
13
var a = 'Hello and Hi'
var A = {
a : 'Hi',
b : {
a : 'Hello',
sayHello : function(){
console.log(this.a) // Hello,
// 这里的this指向的对象是b,因为调用这个sayHello()函数是通过b.sayHello()执行的
console.log(this) // b : {sayHello: ƒ}
}
}
}
A.b.sayHello()
  • x是全局变量,在全局环境下执行,this指向window
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var a = 'Hello and Hi'
var A = {
a : 'Hi',
b : {
a : 'Hello',
sayHello : function(){
console.log(this.a) // Hello,
// 这里的this指向的对象是b,因为调用这个sayHello()函数是通过b.sayHello()执行的
console.log(this) // b : {sayHello: ƒ}
}
}
}
var x = A.b.sayHello
// Hello and Hi
// window
x()

构造函数调用下

  • 如果在一个函数前面加上new关键字来调用,那么就会创建一个连接到该函数的prototype成员的新对象,同时,this会被绑定到这个新对象上
1
2
3
4
function fn(){
console.log(this) // fn()
}
var x = new fn()
  • 在构造函数,new出一个对象时,this指向这个构造函数,new关键字会改变this的指向
1
2
3
4
5
function fn(){
this.a = 'Hello'
}
var x = new fn()
console.log(x.a) // Hello
  • 当用new关键字,返回的是一个对象,this指向的就是那个返回的对象;
1
2
3
4
5
6
function fn(){
this.a = 'Hello'
return {}
}
var x = new fn()
console.log(x.a) // undefined
1
2
3
4
5
6
function fn(){
this.a = 'Hi';
return [];
}
var x = new fn;
console.log(x.a) // undefined
1
2
3
4
5
6
function fn(){
this.a = 'Hi';
return 1;
}
var x = new fn;
console.log(x.a) // Hi
  • 如果返回的不是对象,this还是指向函数的实例,虽然null属于对象,但是返回null依然指向函数实例。
1
2
3
4
5
6
function fn(){
this.a = 'Hi';
return undefined;
}
var x = new fn;
console.log(x.a) // Hi
1
2
3
4
5
6
function fn(){
this.a = 'Hi';
return null;
}
var x = new fn;
console.log(x.a) // Hi

箭头函数下

1
2
3
4
5
6
7
8
9
10
11
var obj = {
foo() {
console.log(this);
},
bar: () => {
console.log(this);
}
}

obj.foo() // {foo: ƒ, bar: ƒ}
obj.bar() // window