JavaScript this

this是JavaScript中一个比较混乱的地方。其实理解JavaScript中的this也挺简单的
在ECMA 3th中有这样的一段描述
There is a this value associated with every active execution context. The this value depends on the caller and the type of code being executed and is determined when control enters the execution context. The this value associated with an execution context is immutable.
翻译中文为
对于每个执行上下文,都有一个 this 值与其相关联。在控制进入执行上下文时,根据调用
者和被执行代码的类型决定这个值。与执行上下文相关联的 this 值是非可变的。
这样我们可以看出关键字 this 总是指向调用该方法的对象。

注意:
(1)对于函数来说,用对象方式调用时,函数中的局部变量并未在对应对象中增加相应的属性(window例外,它会把定义的全局变量添加到window对象相对应得属性中),即函数的局部变量并未添加到prototype链中去。
(2)函数中未使用this访问的变量为局部变量,使用this访问的为对象的属性,属性并不等同局部变量。
示例

<script>
var test = "test";//statements 1
alert( window.test );//statements 2
alert( this.test )//statements 3
function getTest(){
  var gTest = "gTest";//statements 4
  alert( this.gTest );//statements 5
}
var obj=new getTest();//statements 6
alert( obj.gTest ); //statements 7
</script>

 

statements 2,3,5,7 的结果分别为 test,test,undefined,undefined
statements 6 构造时并未将函数局部变量添加到生成对象的gTest的属性中去。所以访问对象的属性gTest时提示未定义
statements 1 全局变量test,添加到window对象的test属性中,所以statements 2的结果为test
statements 3 this为window对象,所以statements 3的结果与statements 1一致

再看一个示例

<script>
function getTest(){
  alert( gTest );//statements 1
  var gTest = "gTest";//statements 2
  alert( this.gTest );//statements 3
  alert( gTest );//statements 4
}
getTest.prototype.gTest = "out";//statements 5
var obj= new getTest();//statements 6
alert( obj.gTest );//statements 7
</script>

 

statements 1,2,3,4,7 的结果为undefined,out,gTest,out
statements 5 添加属性至getTest方法的原型链中。
statements 6 构建对象时statements 1访问的非对象的属性,而是函数变量,但是函数变量并为定义。所以statements 1为undefined而对于statements 3中,对象this代表getTest构建的对象,

所以能访问到相应到原型链中gTest的值。statements 7就更不用说了。

不要将函数的局部变量与对象的属性相混,更不要将对象及函数作用域链相混。
上两个示例为题外话,下面通过示例说明 this 总是指向调用该方法的对象。           

示例 1

<script>
var test = "test";//statements 1
function getTest(  ){
 alert( this.test );//statements 2
 alert( window.test );//statements 3
}
getTest();//statements 4
</script>

 

示例中方法getTest()的调用对象为window,statements 2中的this代表window。
所以 statements 2与statements 3结果一致都为test
示例 2

<script>
var test = "test";//statements 1
function getTest(  ){
 var test = "getTest";//statements 2
 alert( this.test );//statements 3
 alert( window.test );//statements 4
 alert( test );//statements 5
}
getTest();//statements 6
</script>

 

statements 3,4,5 的值为test,test,getTest。statements 3的值并不为getTest,而为test
更加说明this总是指向调用对象即为window。

再看一个示例对于dom对象中的this

<input type="button" id="aButton" value="demo" />
<script type="text/javascript">
 var button = document.getElementById("aButton");//statements 1
 function demo() {    
  this.value = "test";//statements 2
  alert( button.value );//statements 3
 }
button.onclick= demo;//statements 4
alert( button.onclick );//statements 5
</script> 

 

statements 2,3 的结果为生成的随机数并且值一致。
这样可以看出this和button对象具有一致性,其实this代表的就是button对象。

可以参考Firefox脚本调试可以看到this对应的值

JavaScript this

注意在dom中直接调用函数时,它所调用函数的对象为window
<input type="button" id="aButton" value="demo" onclick="demo()" />
<script type="text/javascript">
 var button = document.getElementById("aButton");//statements 1
 function demo() {   
  this.value = "test";//statements 2
  alert( window.value );//statements 3
 }
alert( button.onclick );//statements 4
</script>

statements 2,3 的结果为生成的随机数并且值一致。
这样可以看出this和window对象具有一致性,其实this代表的就是window对象。 

可以参考Firefox脚本调试可以看到this对应的值

JavaScript this

总结:this 总是指向调用该方法的对象,它随执行的上下文环境而改变。

备注:可以使用call及apply函数动态的修改当前的this对象。