JavaScript中函数this指向原理与传参机制详解

作者:异步漫步

时间:2026-10-28

浏览:413

本文深入解析JavaScript中this关键字的指向规则,通过对象方法、全局函数及回调函数等实例,阐明this在不同调用上下文中的变化。同时辨析按值传递与按引用传递的区别,解释对象参数在函数内部修改时的行为差异,帮助开发者准确掌握JS核心概念。

文章目录

本文通过具体实例详细解析JavaScript中函数this关键字的使用方式,旨在为读者提供清晰的参考与学习材料。

this关键字与函数调用的基本关系

在JavaScript开发中,函数内部频繁使用this关键字。this是一个关键字,本质上是一个指针,它指向当前代码执行的环境作用域,通常也被称为上下文(context)。从概念上讲,函数是编程语言中用于重复调用的代码块。在JS中,当函数被赋值给对象的属性时,该函数被称为对象的方法。例如:


var m={};
m.title='title';
m.show=function(){
alert(this.title)
}
m.show()

上述代码展示了将函数作为对象m的方法来调用。在这种情况下,this关键字的指向明确为对象m。

如果直接通过函数名进行调用,则属于普通函数调用。例如:


var a=1212;
function show(){
alert(a)//1212
}
show()// 1212

在全局执行环境中,可以将全局变量视为window对象的属性,而全局函数则被视为window对象的方法。观察以下示例:


var m ={};
m.id='mmm';
m.show=function(){
  alert(this.id);
}
var a={};
a.id='aaa';
a.show=m.show;
a.show(); //aaa

a.show=m.show;  先理解这句话,因为函数是个对象,
m.show=function(){
  alert(this.id)
}

上述表达式表明,a.show与m.show同时引用指向同一个函数对象。


function(){
  alert(this.id)
}

这实际上等同于:


a.show=function(){
  alert(this.id)
}

因此,当调用a.show()时,this指向的是对象a。再来看另一个例子:


var m ={};
m.id='mmm'
m.show=function(){
  alert(this.id)
}
var a={}
a.id='aaa'
a.show=function(){
  m.show()
};
a.show(); //mmm

由此可见,调用a.show()实际上等同于执行m.show()方法,因此this指向的是对象m。

回调函数中的this指向问题

再看以下一个例子,初学者可能对此感到困惑:


var color='red';
var app = {};
app.color="green";
app.paint=function(node){
node.style.color=this.color;
  alert(this.color);
}
function findNode(callback){
  var btn =document.querySelector('.btn');
  callback(btn);//传进来,
}
findNode(app.paint);
alert(this.color); //red 而不是green

在函数传参时,JavaScript采用按值传递(pass-by-value)的方式,而非按引用传递。

因此,当执行findNode(app.paint)时,传入的实际上是:


function(node){
  node.style.color=this.color;
  alert(this.color);
}

即函数引用的副本。由于findNode是在全局作用域中定义的,因此其中的this指向window(在非严格模式下)或undefined(在严格模式下)。

JavaScript参数传递机制:按值与按引用

关于传参机制,传递的是值的副本。


function show(a){
  alert(a)
}

当参数为基本数据类型时,这一概念比较容易理解。


var b=10;
show(b)//alert(10);

而对于对象类型:


var c ={};
c.prop=true;
var showProp=function(obj){
obj.prop=false
}
showProp(c); //c.prop = false

有些人误以为上述示例是按引用传参。实际上,仍然是按值传递。当showProp(c)将c传入函数时,参数obj接收的是c的一个引用副本。在函数内部执行obj.prop=false,相当于修改了这个引用所指向的对象属性,因此外部c.prop也会变为false。

再看下面一个例子:


var c ={};
c.prop=true;
var showProp=function(obj){
  obj = new Object();
  obj.prop=false
  return obj;
}
showProp(c);
alert(c.prop); //true

这里虽然修改了传入的obj,但如果按照所谓的“按引用传参”,外部对象的修改应该会反映出来。然而,示例中重新赋值obj为新对象,并未改变外部c的引用,因此外部c.prop仍为true。

希望本文的阐述能对大家的JavaScript程序设计有所帮助。

实用工具推荐

电子包浆

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

使用 ›
图片压缩

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

使用 ›
相关文章