this用法

前言:this参数为函数的一个参数,在面向对象编程中非常重要。在JavaScript中,它的值取决于函数调用的模式,模式不同this指向就可能不同。JavaScript中共有以下4种调用模式:

1)方法调用模式;

2)函数调用模式;

3)构造函数模式;

4)apply/call模式。

方法调用模式

当一个函数被保存为对象的一个属性时,我们称此函数为方法。因此,方法是针对对象而言,当一个方法被调用时,this被绑定到该对象。通过obj.dosth或者obj[dosth]的方式,可以实现方法调用。如下:

var obj ={
  value:3,
  dosth:function(){
    return this.value;//通过obj.do()调用时,this指向obj
  }
}
console.log(obj.dosth());//3

通过obj.dosth()调用方法,因此dosth方法中的this指向obj,因此this.value返回了obj.value的值

函数调用模式

当一个函数并非一个对象的属性时,那么它就是被当做一个函数来调用的。此时,相当于再全局环境中调用此函数,this指向全局对象。

var dosth = function(){
  return this.value;
}
console.log(dosth());//undefined
var value= 2;
console.log(dosth());//2

以函数模式调用时this指向全局对象这一特性,可以说是一个设计错误,它会导致内部函数调用时this无法指向外部函数的this(很多情况下我们是希望指向外部函数的this)。如下:

var value = 2;
var obj ={value:3}
obj.double = function(){
  var helper = function(){
    this.value = this.value*2;
  }
  helper();
}
obj.double();
console.log("obj的value值为:"+obj.value+",window的value值为:"+value);//obj的value值为:3,window的value值为:4

可以发现,执行了obj.double()后,obj.value值并没有变化,而全局变量value的值*2了。因为helper虽然在obj.double内部,但其采用函数模式调用时,this指向的是window而不是obj。解决这个问题也很简单:

var value = 2;
var obj ={value:3}
obj.double = function(){
  var that = this;//将this赋值给that
  var helper = function(){
    that.value = that.value*2;
  }
  helper();
}
obj.double();
console.log("obj的value值为:"+obj.value+",window的value值为:"+value);//obj的value值为:6,window的value值为:2

构造函数调用模式

当一个函数采用new操作符调用时,它就成为构造函数。也就是说,构造函数只是普通函数,只是在new的那一刻,其被成为构造函数。通过new操作符调用一个函数时,new操作符背后干了三件事:

1)创建一个连接到该函数的prototype成员的新对象;

2)将构造函数的作用域赋给新对象;

3)执行构造函数代码;

4)返回新对象。

通过以上第2步,this对象就指向了新对象。

apply/call调用模式

apply/call是最直观的可以看出this指向的调用模式,在apply/call中指定的第一个参数就是要绑定给this的值。同样是上面的例子,改变调用方式后,结果便不一样了。

var value = 2;
var obj ={value:3}
obj.double = function(){
  var helper = function(){
    this.value = this.value*2;
  }
 helper.call(obj);//改变调用方式
}
obj.double();
console.log("obj的value值为:"+obj.value+",window的value值为:"+value);//obj的value值为:6,window的value值为:2

不过要注意,在非严格模式下,当第一个参数为null或undefined时,this将指向window。

posted @ 2017-05-24 22:52  小丸子的城堡  阅读(264)  评论(0编辑  收藏  举报