浅谈javascript关键字"this"

 

学习过javascript或者正学学习javascript中的人对里面的关键字并不陌生,甚至如影随至,理解并熟练试用this关键字能够让书写出来的代码精简而又漂亮,那么此文就与大家一起学习一下this关键字在javascript中的常见用法。

    首先我不得不说this关键字在代码中的具体指定,取决于函数运行过程中的调用对象,并在此对象调用过程中保持不变。
    全局函数中的"this",看下面代码:

1 var value=3;
2 function test(){
3 this.value=5;
4 }
5 test();

console.log检测一下发现全局value值发生改变。不难理解这里的this当然指的就是window了,因为test()其实就是window.test(),函数的调用者是window,那么此时this就指定window了,其实我们可以总结出一句话,全局函数里,this指向的就是window。

   构造函数中的"this",看下面的代码:

function Foo(name,age){
  this.name=name;
  this.age=age;
}
var test=new Foo("liang",20);
alert(test.name)  //liang

在构造函数中的this,指定的就是未来构造出来的对象了。学过面向对象的应该都知道,构造器是用来封装未来对象的方法和属性的,调用者是未来的对象,那当然this就指的是调用的对象了。

在HTML中试用的this,先看一段HTML代码:

<div>
  <ul>
     <li>1</li>
     <li>2</li>
     <li>3</li>
     <li>4</li>
  </ul>
</div>

在看相关的js代码:

var arr=document.getElementsByTagName("li");
var length=arr.length;
for(var i=0;i<length;i++){
arr[i].onmouseover(function(){
this.className="gl";
})
}

这是平时最常用的鼠标经过定义事件,方法的调用对象是dom节点,所以此时的this就是指向当前触发事件的dom对象。

但是需要注意的是在addEventListener和attachEvent事件注册中this有点小小的区别:

<div id="tt">点击测试</div>

在IE下代码:

function test(){
console.log(this)
}
document.getElementById("tt").attachEvent("onclick",test);

点击测试发现输出//[object Window],说明此时事件已经冒泡了,this指向了window;这就是为什么在一些框架中需要用call或者apply来改变this的原因。

在看看Firfox或者Chrom中的代码:

function test(){
console.log(this);
}
document.getElementById("tt").addEventListener("click",test,false);

点击测试发现输出://[object HTMLParagraphElement]。this指向的是当前点击的dom节点。

闭包中的this,看下面的代码:

var test="global";
function foo(){
   var test="local";
   return function(){
 alert(this.test);
}
}
foo()();//global;

返回的闭包函数里this指向的是window。如何理解呢,一步步分析,foo()执行后返回的是一个匿名函数,这个匿名函数其实就变成了一个全局函数,再往下foo()(),其实就变成了window调用返回的匿名函数了,调用者是window,返回的匿名函数中的this当然指代的就是window了.

setTimeout、setInterval和匿名函数中的this:

 var name = "Bob";  
 var nameObj ={  
     name : "Tom",  
    showName : function(){  
       alert(this.name);  
    },  
     waitShowName : function(){  
          setTimeout(this.showName, 1000);  
     }  
};  

nameObj.waitShowName();//输出Bob

在浏览器中setTimeout、setInterval和匿名函数执行时的当前对象是全局对象window 这一点一定要切记。

嵌套函数中的this,看下面的代码:

var o={
       m:function(){
           var self=this;
           console.log(this===o);
        f();
           function f(){
               console.log(this===o);
               console.log(self===o);
           }
       }
   }
o.m();
true
false
true

这里不得不说一下方法调用和函数调用很重要的一个区别:就是调用上下文。嵌套的函数不会从调用它的函数中继承this.如果嵌套函数作为方法调用,其中this的值指向调用它的对象。如果嵌套函数作为函数调用,其this值不是全局对象就是undifined。很多人误以为调用嵌套函数时this会指向调用外层函数的上下文,如果你想访问这个外部函数的this值。需要将this值保存在一个变量里,这个变量和内部函数都在同一个作用域内。

总结一下:一个方法里的this指向的是调用这个方法的那个对象,如果没有被某个对象调用,则这个函数里的this指向undefined.但js引擎会私自做些处理,当this指向undefined 或者 null的时候,this会指向全局对象。

posted @ 2012-10-22 15:42  黑暗骑士之“闪”  阅读(262)  评论(0编辑  收藏  举报