JasmineHua's blog

javascript中this的指向

前言

JavaScript的函数存在定义时上下文运行时上下文以及上下文是可以改变的的概念。所以this的指向是随着它上下文的改变而改变的。

函数调用时的this

this最终指向的是调用它的对象,这里的函数f()实际是被Window对象调用的:

1
2
3
4
5
6
function f(){
var x = "花";
console.log(this.x); //undefined
console.log(this); //Window
}
f(); //window.f()

下面函数是被对象o调用的,所以this指向o;

1
2
3
4
5
6
7
var o = {
x:"花",
m:function(){
console.log(this.x); //花
}
}
o.m();

如果嵌套函数作为方法调用,其this指向调用它的对象。如果嵌套函数作为函数调用,其this值是全局对象(非严格模式下)或者undefined(严格模式下)。

1
2
3
4
5
6
7
8
9
10
11
12
var o = {
x:"花",
m:function(){
console.log(this.x); //花
f()
function f(){
console.log(this.x); //undefined
console.log(this) //window
}
}
}
o.m()

call(),apply(),bind()的this

通过call(),apply(),bind(),我们可以自行改变this的指向。例子如下

1
2
3
4
5
function f(){return this.x}
var o = {x:1}
f.call(o) //=> 1:函数f内this指向o。
f.apply(o) //同上
f.bind(o)() //同上

如需了解更多,请看我的另一篇文章javascript中call,apply,bind的使用方法)

构造函数的this

构造函数执行时,上下文(this)会被指定为这个新实例。

1
2
3
4
5
function F(){
this.x = "花";
}
var o = new F();
console.log(o.x); //花

但构造函数有一个特殊情况,就是如果构造函数返回了一个“对象”,那么这个对象会取代整个new出来的结果。也就是说创建出来的对象不是构造函数的实例。

1
2
3
4
5
6
7
function F(){
this.x = "花";
return {}
}
var o = new F();
console.log(o.x); //undefined
console.log(o); //Object {}

当然如果返回值不是对象类型,就不会被取代。

1
2
3
4
5
6
7
function F(){
this.x = "花";
return 1
}
var o = new F();
console.log(o.x); //花
console.log(o); //F {x: "花"}

另一篇文章javascript构造函数详细讲解了构造函数

总结

  1. 函数作为方法调用,其this指向调用它的对象,作为函数调用,其this值是全局对象(非严格模式下)或者undefined(严格模式下);
  2. call(),apply(),bind()改变函数的this指向;
  3. 构造函数没有返回值或返回值不是对象类型时,this指向新实例。