JavaScript中this指向详解与call/apply/bind方法解析
本文详细解析JavaScript中函数this的指向规则,涵盖普通函数、构造函数、对象方法、事件绑定、定时器及立即执行函数等场景。同时深入讲解call、apply和bind三个改变this指向的方法,对比其语法差异、参数传递方式及典型应用场景,帮助开发者准确掌握this机制。
一、 函数内 this 的指向
this 的具体指向取决于函数的调用时机与方式,通常指向调用该函数的对象。
1、普通函数
function fn(){
console.log('普通函数的this:'+this);
}
fn()
代码执行后的输出结果如下:

由此可见,在普通函数直接调用时,this 默认指向全局对象 window。
2、构造函数
function Star(){
console.log('构造函数的this:'+this);
}
new Star()
代码执行后的输出结果如下:

可以看出,当通过 new 关键字调用构造函数时,this 指向新创建的实例对象。
3、对象方法
var o = {
print: function(){
console.log('对象方法的this:'+this);
}
}
o.print()
代码执行后的输出结果如下:

结果表明,当作为对象的方法被调用时,this 指向该方法所属的对象。
4、事件绑定方法
若为按钮元素注册了事件监听器,此时 this 的指向情况如何?
假设存在一个 button 元素,为其添加点击事件处理函数,代码如下:
<body>
<button>按钮</button>
<script>
var btn = document.querySelector('button');
btn.onclick = function(){
console.log('绑定事件的this:'+this);
}
</script>
</body>
点击按钮后,控制台输出如下:

可见,在事件处理函数中,this 指向绑定该事件的目标元素。
5、定时器函数
编写一个定时器函数,设定在 1 秒后执行该函数。
window.setTimeout(function(){
console.log('定时器的this:'+this);
},1000)
代码执行后的输出结果如下:

结果显示,定时器回调函数中的 this 指向全局对象 window。
6、立即执行函数
定义并执行一个立即执行函数(IIFE):
(function(){
console.log('立即执行函数的this:'+this);
})();
代码执行后的输出结果如下:

结果表明,立即执行函数中的 this 同样指向全局对象 window。
综上所述,各类函数调用时的 this 指向规律如下:
| 调用方式 | this指向 |
|---|---|
| 普通函数调用 | window |
| 构造函数调用 | 实例对象,原型对象里面的方法也指向实例对象 |
| 对象方法调用 | 该方法所属对象 |
| 事件绑定方法 | 绑定事件对象 |
| 定时器函数 | window |
| 立即执行函数 | window |
二、改变函数内部 this 指向
函数的 this 指向并非固定不变,可以通过特定方法进行修改。主要方法包括 call、apply 和 bind,前两者在原型对象章节已提及,此处直接通过示例说明。
1、call 方法
首先定义一个对象和一个普通函数。
var o = {
name:'xl'
}
function fn(){
console.log(this);
}
此前已说明,普通函数内的 this 指向 window。若希望将 this 指向对象 o,应使用以下代码:
fn.call(o)
执行后的输出结果为:

此时,this 已成功指向对象 o。
2、apply 方法
用法与 call 类似。
var o = {
name:'xl'
}
function fn(){
console.log(this);
}
fn.apply(o);
代码执行后的输出结果为:

3、bind 方法
bind() 方法不会立即执行函数,但能改变函数内部的 this 指向。
语法格式如下:
fun.bind(thisArg, arg1, arg2, ...)
其中,thisArg 指定函数运行时绑定的 this 值;arg1, arg2 等表示传递的其他参数。该方法返回一个修改了 this 指向的原函数副本。
因此,若仅需改变 this 指向而不希望立即执行函数,可使用 bind。
以下示例延续上述案例:
var o = {
name:'xl'
}
function fn(){
console.log(this);
}
var f = fn.bind(o);
f();
代码执行后的输出结果为:

需注意:由于 bind() 不执行函数,而是返回一个新函数,因此需将该返回值赋给变量 f,再通过调用 f 来执行原函数逻辑。
三、call apply bind 总结
1、相同点
三者均能改变函数内部的 this 指向。
2、不同点
call和apply会立即调用函数,并改变函数内部 this 指向。-call和apply传递的参数不一样, call 传递参数 aru1, aru2…形式 apply必须数组形式[arg]。bind不会立即调用函数,仅改变函数内部 this 指向。
3、应用场景
call常用于实现继承。apply常与数组操作相关,例如借助数学对象求数组的最大值或最小值。bind用于不执行函数但需改变 this 指向的场景,例如修改定时器内部的 this。
总结
本文到此结束,希望能为读者提供有益帮助,欢迎持续关注本站获取更多技术内容!
JS语法错误会阻止加载吗?区分SyntaxError与资源加载失败
2026-11-05 16:08:46
JavaScript常见SyntaxError语法错误排查与修复方法
2026-11-05 13:58:44
JS中slice、substring和substr截取字符串的区别
2026-11-05 13:43:47
JS 转 TS 手动迁移最佳实践:从配置 tsconfig 到消除 any 类型
2026-11-05 11:53:32
为什么JS数组push后得到的是数字而不是数组?
2026-11-05 09:59:18
相关标签:
