浅谈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会指向全局对象。