本文深入解析JavaScript中this关键字的指向逻辑,通过对比方法直接赋值与函数内部调用的两种场景,阐明“调用者”与“触发者”的区别。文章指出this始终指向实际执行方法的对象,而非定义或发起调用的对象,帮助开发者准确理解闭包与上下文绑定的核心差异。
JavaScript中this指向:方法调用与触发的区别
在JavaScript中,this关键字是一个颇具趣味但也容易令人困惑的概念,其指向规则常常让初学者感到难以捉摸。
要准确理解这一关键字,关键在于厘清两个核心概念:方法的调用(Calling)与方法的触发(Triggering)。
首先,我们来看一段具体的代码示例。
代码示例与现象分析
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>function</title>
<script>
function showThis(){
console.info(this);
}
function Test1(){
this.f=showThis;
}
function Test2(){
this.f=function(){
showThis();
}
}
showThis();//window
new Test1().f();//Test1
new Test2().f();//window
</script>
</head>
<body>
</body>
</html>
调用者与触发者的核心差异
代码第20行输出window对象,这符合全局调用的常规认知;然而,第21行输出的是Test1的实例对象,第22行却再次输出window对象。观察Test1和Test2的构造函数可知,两者的f方法最终都执行了showThis函数,但showThis内部的this指向却截然不同。原因在于:Test1中的f方法直接引用了showThis,因此new Test1().f()是以Test1的实例作为调用者直接执行showThis,此时this指向该实例。相反,new Test2().f()是在Test2的实例方法f内部触发了全局对象的showThis方法,这里的调用者是window,因此this指向window,而非触发调用的Test2实例。
由此可以得出结论:this的指向取决于实际的调用者(即谁执行了该方法),而触发者仅负责推进调用者去执行指定的方法。