JavaScript中this关键字的8种使用场景与指向详解

作者:小圆点

时间:2026-10-29

浏览:545

本文详细解析JavaScript中this关键字的多种使用场景。涵盖HTML内联事件、DOM绑定、类定义、原型方法、CSS表达式及内部函数等8种情况,深入探讨this在不同上下文中的指向差异,特别是结合IE attachEvent与DHTML赋值时的行为区别,帮助开发者理解并避免常见的this指向陷阱。

文章目录

JavaScript this关键字概述

在C++、C#和Java等经典面向对象编程语言中,this关键字是开发者非常熟悉的概念。尽管初学阶段可能感到晦涩,但一旦掌握,其指向明确且使用便捷。JavaScript同样提供了this关键字,然而其实际表现比传统面向对象语言更为复杂和多变。



接下来,我们将深入探讨JavaScript中this关键字在不同场景下表现出的复杂性。



HTML内联与DOM事件中的this指向

第一种情况:在HTML元素的事件属性中,以内联方式直接使用this关键字。



<div onclick="


// 可以在里面使用this



">division element</div>



通常的做法是在此处调用类似 javascript: EventHandler(this) 的形式。但实际上,这里可以执行任何合法的JavaScript语句,甚至可以在其中定义类(尽管这会生成一个内部类)。其背后的原理是,脚本引擎会为该div元素实例生成一个匿名的成员方法,并将onclick属性指向该方法。



第二种情况:通过DOM方式在事件处理函数中使用this关键字。



 

代码如下:

<div id="elmtDiv">division element</div>
<script language="javascript">
var div = document.getElementById('elmtDiv');
div.attachEvent('onclick', EventHandler);
function EventHandler()
 {  
// 在此使用this
 }  
</script>

在这种写法中,EventHandler函数内的this关键字指向的是IE浏览器的window对象。这是因为EventHandler只是一个普通函数,在调用attachEvent后,脚本引擎对其的调用与div对象本身没有直接关联。此时查看EventHandler的caller属性,其值为null。若需在此方法中获取div对象的引用,应使用 this.event.srcElement。



第三种情况:通过DHTML方式在事件处理函数中使用this关键字。



<div id="elmtDiv">division element</div>


<script language="javascript">


var div = document.getElementById('elmtDiv');


div.onclick = function()


 {

// 在此使用this


 };

</script>



此处的this关键字指向的是div元素对象的实例。通过DHTML方式直接为div.onclick赋值一个EventHandler方法,相当于为div对象实例添加了一个成员方法。这与第一种方式的区别在于:第一种使用HTML内联方式,脚本引擎会生成匿名方法;而DHTML方式下,脚本解析引擎不会再生成额外的匿名方法。



类定义与原型方法中的this

第四种情况:在类定义中使用this关键字。



 

代码如下:

function JSClass()
  {  
var myName = 'jsclass';
this.m_Name = 'JSClass';
  }  
JSClass.prototype.ToString = function()
  {  
alert(myName + ', ' + this.m_Name);
  };  
var jc = new JSClass();
jc.ToString();

这是JavaScript模拟类定义中this的使用方式,与其他面向对象语言的情况非常相似。但需要注意的是,成员属性和方法必须使用this关键字来引用。运行上述程序会提示myName未定义,因为myName是局部变量,而非实例属性。





第五种情况:为脚本引擎内部对象添加原型方法时使用this关键字。



  

代码如下:

Function.prototype.GetName = function()
  {  
var fnName = this.toString();
fnName = fnName.substr(0, fnName.indexOf('('));
fnName = fnName.replace(/^function/, '');
return fnName.replace(/(^\s+)|(\s+$)/g, '');
  }  
function foo(){}
alert(foo.GetName());

这里的this指代的是被添加原型方法的类的实例。这与第四种类定义中的情况相似,没有特别之处。



复杂场景下的this指向陷阱

第六种情况:结合第二种和第四种情况,讨论一个容易混淆的this使用场景。



 

代码如下:

function JSClass()
  {  
this.m_Text = 'division element';
this.m_Element = document.createElement('DIV');
this.m_Element.innerHTML = this.m_Text;
this.m_Element.attachEvent('onclick', this.ToString);
  }  
JSClass.prototype.Render = function()
  {  
document.body.appendChild(this.m_Element);
  }       
JSClass.prototype.ToString = function()
  {  
alert(this.m_Text);
  };  
var jc = new JSClass();
jc.Render();
jc.ToString();

简要说明结果:页面运行后显示“division element”。点击该文字后,将显示“undefined”。这是因为attachEvent绑定时,this指向window,导致this.ToString执行时this.m_Text无法从JSClass实例中获取。



CSS表达式与内部函数中的this

第七种情况:在CSS的expression表达式中使用this关键字。



 

代码如下:

<table width="100" height="100">
<tr>
<td>
<div style="width: expression(this.parentElement.width);
height: expression(this.parentElement.height);">
division element</div>
</td>
</tr>
</table>

此处的this与第一种情况类似,指代的是div元素对象实例本身。



第八种情况:在函数的内部函数中使用this关键字。



 

代码如下:

function OuterFoo()
  {  
this.Name = 'Outer Name';
function InnerFoo()
      {  
var Name = 'Inner Name';
alert(Name + ', ' + this.Name);
      }  
return InnerFoo;
  }  
OuterFoo()();

运行结果显示为“Inner Name, Outer Name”。根据第二种情况的解释,结果似乎应该是“Inner Name, undefined”才更合理。但正确结果确实是前者,这是由JavaScript的变量作用域机制决定的。如需深入了解,建议参考“原来JScript中的关键字'var'还是有文章的”一文及其回复。



总结:JavaScript的面向对象特性

综上所述,JavaScript中this最根本的特性仍与面向对象语言中的定义一致。之所以出现多种看似混乱的使用方式,是因为JavaScript语言(包括解释器和语言本身)在实现上遵循的是对象基(Object-based)模式,其所有数据类型均为对象,包括Object这一超级对象。然而,在运行时(runtime)并未遵循完备的面向对象特性,从而导致this的指向出现混乱。



JavaScript中还有哪些地方使用了this?目前能想到的就这些,欢迎讨论和补充。


实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章