深入解析JavaScript中this指针的指向规则
本文深入探讨JavaScript中this指针的指向机制。通过多个代码示例,解析全局函数、对象方法、构造函数以及返回值对this的影响。明确this在定义时不确定,仅在执行时由调用者决定。涵盖非严格模式下的默认指向、new关键字的作用及return语句的例外情况,帮助开发者准确理解this行为。
JavaScript中this指针的指向规则
深入解析JavaScript中this指针的指向规则
首先需要明确的是,this的指向在函数定义阶段是无法确定的,只有在函数实际执行时才能确定this的具体指向。从本质上看,this最终指向的是调用该函数的对象(注:这一表述存在局限性,下文将解释其原因。尽管网络上多数文章持此观点,且在许多场景下适用,但这种理解并不完全准确,这也是导致this概念难以捉摸的原因)。接下来将对这一机制进行深入探讨。
学习this指针的意义在于:若你熟悉函数式编程或面向对象编程,便知其重要性;若未接触过,可暂略过本文,但若有兴趣,建议阅读,因为掌握this是JavaScript开发的核心基础。
全局与对象调用下的this指向
示例1:
function a(){
var user = "追梦子";
console.log(this.user); //undefined
console.log(this); //Window
}
a();
根据前述观点,this最终指向调用它的对象。在示例1中,函数a实际上是被Window对象调用的,以下代码可验证这一点。
function a(){
var user = "追梦子";
console.log(this.user); //undefined
console.log(this); //Window
}
window.a();
上述代码逻辑相同。实际上,alert也是window对象的一个属性,同样由window对象调用。
示例2:
var o = {
user:"追梦子",
fn:function(){
console.log(this.user); //追梦子
}
}
o.fn();
此处的this指向对象o,因为函数fn是通过o.fn()执行的,因此指向对象o。再次强调,this的指向在函数创建时无法确定,仅在调用时确定,且指向调用者。务必厘清这一概念。
示例1和示例2的表述并不严谨,以下示例可推翻上述理论。
要彻底理解this,需参考后续几个示例。
示例3:
var o = { user:"追梦子",
fn:function()
{ console.log(this.user); //追梦子 } }
window.o.fn();
这段代码与前述代码相似,但此处this并未指向window。若按前述理论,this应指向调用它的对象。此处补充说明:window是JavaScript的全局对象,我们创建的变量实际上是window的属性,因此可通过window访问对象o。
暂不解释为何此例中this未指向window,继续观察以下代码。
var o = {
a:10,
b:{
a:12,
fn:function(){
console.log(this.a); //12
}
}
}
o.b.fn();
此处同样由对象o调用,但this并未指向它。这是否意味着前文所述有误?并非如此,仅是前文表述不够严谨。接下来补充关键说明,即可彻底理解this的指向问题。
this指向的三种基本情况
情况1:若函数中存在this,且未被上一级对象调用,则this指向window。需注意,在JavaScript严格模式下,this指向undefined。本文暂不讨论严格模式,感兴趣者可自行查阅相关资料。
情况2:若函数中存在this,且被上一级对象调用,则this指向该上一级对象。
情况3:若函数中存在this,且该函数包含多个对象,即使由最外层对象调用,this仍指向其上一级对象。示例3可证明此点。若不信,请继续观察后续示例。
var o = {
a:10,
b:{
// a:12,
fn:function(){
console.log(this.a); //undefined
}
}
}
o.b.fn();
尽管对象b中无属性a,this仍指向对象b,因为this仅指向其上一级对象,无论该对象是否包含所需属性。
函数赋值与最后调用者的关系
还有一种特殊情况,见示例4:
var o = {
a:10,
b:{
a:12,
fn:function(){
console.log(this.a); //undefined
console.log(this); //window
}
}
}
var j = o.b.fn;
j();
此处this指向window,是否令人困惑?原因在于未理解关键语句,该语句至关重要。
this永远指向最后调用它的对象,即执行时的调用者。示例4中,虽然函数fn被对象b引用,但在将fn赋值给变量j时并未执行,因此最终指向window。这与示例3不同,示例3直接执行了fn。
this的指向虽复杂,但本质一致,仅在不同场景下表现不同。前文总结存在细微偏差,并非错误,而是环境不同导致结果不同,需逐步体会。
构造函数中的this指向
构造函数版this:
function Fn(){
this.user = "追梦子";
}
var a = new Fn();
console.log(a.user); //追梦子
此处对象a之所以能访问函数Fn内部的user,关键在于new关键字改变了this的指向,使其指向对象a。之所以判定a为对象,是因为new关键字用于创建对象实例。结合示例3理解,变量a创建了Fn的一个实例,这相当于将Fn函数复制了一份到对象a中。此过程仅完成创建而未执行,由于调用Fn的是对象a,故this自然指向a。Fn中为何存在user,是因为通过new关键字已将Fn复制至对象a中。
除上述情况外,还可手动改变this指向,详见《JavaScript中call,apply,bind方法的总结》一文,详细说明了手动更改this指向的方法。
构造函数中return语句对this的影响
更新一个小问题:当this遇到return时
function fn()
{
this.user = '追梦子';
return {};
}
var a = new fn;
console.log(a.user); //undefined
再看一个示例
function fn()
{
this.user = '追梦子';
return function(){};
}
var a = new fn;
console.log(a.user); //undefined
再来一个示例
function fn()
{
this.user = '追梦子';
return 1;
}
var a = new fn;
console.log(a.user); //追梦子
function fn()
{
this.user = '追梦子';
return undefined;
}
var a = new fn;
console.log(a.user); //追梦子
何意?
若返回值为对象,则this指向该返回对象;若返回值非对象,则this仍指向函数实例。
function fn()
{
this.user = '追梦子';
return undefined;
}
var a = new fn;
console.log(a); //fn {user: "追梦子"}
此外,尽管null也是对象,但此处this仍指向函数实例,因null具有特殊性。
function fn()
{
this.user = '追梦子';
return null;
}
var a = new fn;
console.log(a.user); //追梦子
严格模式与new操作符的补充说明
知识点补充:
1. 在严格模式下,默认this不再是window,而是undefined。
2. new操作符会改变函数this的指向。前文已提及,但未深入讨论,网上也较少涉及,故在此补充说明。
function fn(){
this.num = 1;
}
var a = new fn();
console.log(a.num); //1
为何this指向a?首先,new关键字创建一个空对象,随后自动调用apply方法,将this指向该空对象,从而替代函数内部的this。
D3.js 比例尺与坐标轴的配置详解
2026-11-05 16:54:46
JavaScript怎么遍历对象的Symbol键和不可枚举属性
2026-11-05 13:13:39
封装一个健壮的JS字符串判空工具函数
2026-11-05 12:16:14
JavaScript合并数组的三种常用方法:concat、扩展运算符与push
2026-11-05 11:22:29
JavaScript立即执行函数(IIFE)是什么及基本语法
2026-11-05 10:51:19
