JavaScript中this关键字指向机制详解

作者:交互手记

时间:2026-10-27

浏览:639

本文深入解析JavaScript中this关键字的指向规则。通过全局函数、事件处理函数及对象方法三种场景,阐明this始终指向调用者的核心逻辑。重点剖析DOM事件绑定中赋值与引用的区别,并介绍利用apply和call手动改变this指向的方法,帮助开发者避免常见误区。

文章目录

首先抛出一个核心结论:在JavaScript中,this关键字始终指向函数(或方法)的调用者。

全局函数中的this指向

全局函数场景

参考以下代码示例:

function introduce() {
alert("Hello, I am Laruence\r\n");
}

针对上述定义的函数,我们需要确定this关键字的具体指向。

正如前文关于JavaScript作用域的讨论所述,定义在全局作用域下的函数,其所有者即为当前页面环境,也就是window对象。

因此,我们将函数名用引号包裹起来进行描述,是因为在全局作用域定义的函数,本质上就是window对象的一个方法属性。

基于此,我们既可以直接通过函数名进行调用,也可以通过window.方法名的方式进行调用。在这两种调用方式下,函数内部的this关键字均指向其所有者,即window对象。

若我们直接查看window对象的introduce属性,将会得到如下结果:

代码示例如下:

var name = "I am Laruence";
function introduce() {
alert(this.name);
}
alert(window.introduce);

观察上述代码,读者可能会产生疑问:既然全局函数是window对象的方法,而全局变量又是window对象的属性(如JavaScript作用域章节所述),那么在全局函数内部是否可以通过this关键字来访问这些全局变量?

答案是肯定的。当调用introduce函数时,通过this.name即可获取到全局变量name的值,从而输出"I am Laruence"。

事件处理函数中的this机制

事件处理函数场景

对于this关键字的困惑,很大程度上源于将函数用作事件处理程序时的行为差异。

HTML代码示例:

<input id="name" type="text" name="name" value="Laruence" />例如,我们需要在点击id为"name"的输入框时,显示该输入框的value值。对应的JavaScript代码可以编写如下:
function showValue() {
 alert(this.value);
}
document.getElementById('name').onclick = showValue;

上述代码运行正常,但为何如此?前文提到this指针永远指向函数所有者,且全局函数的所有者是window对象,这里似乎存在矛盾。

若能提出此疑问,说明读者进行了深入思考;否则建议重新阅读前文,以免产生误解。

确实,showValue函数定义在全局对象中,问题的关键在于onclick事件绑定的机制。

在JavaScript中,一切皆对象,函数和方法也是对象的属性,区别仅在于函数具有可执行的内部属性。因此,在上述代码中,对onclick属性赋值处理器时,实际上是将showValue函数引用赋给了id为name的DOM输入框对象的onclick属性。

换言之,我们将showValue函数“复制”(引用)给了name输入框对象的onclick属性。若此时查看该onclick属性,会发现:

代码验证如下:

function showValue() {
alert(this.value);
}
document.getElementById('name').onclick = showValue;
alert(document.getElementById('name').onclick);

因此,当点击事件触发时,程序会调用name输入框的onclick方法。此时,this关键字自然指向触发事件的DOM元素,即name输入框本身。

然而,存在一种容易混淆的写法:

HTML内联事件代码:

function showValue() {
alert(this.value);
}
<input id="name" type="text" name="name" value="Laruence" onclick="showValue()"/>

这种写法往往无法按预期运行,原因何在?

关键在于,此处并非赋值操作,而是引用传递。

对比两种onclick的写法,前一种方式使用的是:

dom.onclick = showvalue; // 注意:没有调用括号()

而后一种方式使用的是:

onclick = "showvalue()" // 注意:包含调用括号()

这一差异侧面反映了两者的本质区别:前者是赋值(将函数对象赋给属性),后者是引用(字符串形式的代码执行)。若此时查看输入框的onclick属性,执行:

alert(dom.onclick);

观察返回结果即可理解差异所在。

此处分享一个有趣的示例,建议在IE浏览器环境下测试:

<img src="xxx" onerror="alert(1); function hi() { alert(2); }" />

手动改变this指向的方法

改变this指向的方法

既然明确了this指向的原理,我们该如何主动控制this的指向目标?

针对上述事件处理函数的场景,可采用以下几种写法:

dom.onclick = showValue(); dom.onclick = function() { alert(this.value) ;} <input onclick="alert(this.value);" /> // 注意前文引用的嵌入方式 dom.addEventListener(dom, showValue, false); // 仅Firefox支持

在非事件处理函数的场合,可以使用apply或call方法来手动改变this关键字的指向。

具体示例如下:

代码实现:

var laruence = {
name : 'laruence',
age : 26,
position : 'Senior PHP Engineer',
company : 'Baidu.inc'
};
function introduce() {
 alert(this.name);
}
introduce.call(laruence);

实用工具推荐

电子包浆

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

使用 ›
图片压缩

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

使用 ›
相关文章