JavaScript中this关键字的五种指向场景详解
本文详细解析JavaScript中this关键字的五种不同指向情况。涵盖全局范围、普通函数调用、对象方法调用、通过call/apply/bind显式绑定以及构造函数调用场景。通过代码示例说明不同调用方式下this的具体指向,帮助开发者准确理解并应用this机制。
JavaScript this 指向概览
JavaScript 对 this 的处理机制与其他语言截然不同。在五种不同的调用场景下,this 的指向各不相同。
一个常见的理解是:谁调用了这个函数,this 就指向谁。
全局范围内的 this 指向
一、全局范围
在全局作用域中使用 this,它指向全局对象(在浏览器环境中为 window)。
var name = 'name1';
console.log(name);
this.name = 'name2';
console.log(name);
console.log(this.name);
window.name = 'name3';
console.log(name);
console.log(this.name);
console.log(window.name);

普通函数调用中的 this
二、函数调用
直接调用一个函数时,this 默认指向全局对象(浏览器端为 window)。
var name = 'name1';
function sayName(){
console.log(name);
console.log(this);
}
sayName();
window.sayName();
可以看到

还有一些常见情况,根据“谁调用方法就指向谁”的原则,需要仔细分析 this 的指向。
// 全局 name
var name = 'name1';
var obj = {
name: 'name2',
sayName: function(){
// 调用它的时候 this指向全局
return function(){
console.log(this.name);
};
},
changeName: function(){
// 调用它的时候 this指向全局
setTimeout(function(){
this.name = 'name3';
},0);
}
};
obj.sayName()();
obj.changeName();
setTimeout(function(){
console.log(name);
console.log(obj.name);
},0);

对于类似匿名函数的情况,默认情况下它们是被全局对象(浏览器下的 window)调用的。要正确让 obj 调用,需要明确指代关系。
可以使用 that 变量保存 this 的引用以进行后续操作,或者通过匿名函数传值,也可以使用 call/apply/bind 来改变上下文。
var name = 'name1';
var obj = {
name: 'name2',
sayName: function(){
var that = this;
return function(){
console.log(that.name);
};
},
changeName: function(){
var that = this;
setTimeout(function(){
that.name = 'name3';
},0);
}
};
obj.sayName()(); // name2
obj.changeName();
setTimeout(function(){
console.log(name); // name1
console.log(obj.name); // name3
},0);
对象方法调用时的 this
三、作为对象方法的调用
这类似于前面提到的 obj.sayName() 或 obj.name 等形式。
此时,this 会指向该对象 obj。
使用 call/apply/bind 改变 this
四、call/apply/bind 的调用
当使用 Function.prototype 上的 call、apply 或 bind 方法时,函数内部的 this 会被显式设置为这些方法调用的第一个参数。
具体使用方法
我们可以稍微修改上面的代码,即可看到 this 指向的变化。
var name = 'name1';
var obj = {
name: 'name2',
sayName: function(){
// 返回一个默认全局的函数
return function(){
console.log(this.name);
};
},
changeName: function(){
// 返回一个默认全局的函数
setTimeout(function(){
this.name = 'name3';
// 然后将该函数绑定给this(当前obj对象)
}.bind(this),0);
}
};
// obj.sayName()这个函数,让obj来调用
obj.sayName().call(obj);
// 让this(也就是全局对象)来调用
obj.sayName().apply(this);
obj.changeName();
setTimeout(function(){
// 输出更改之后,全局name的值
console.log(name);
// 输出更改之后,obj对象中 name的值
console.log(obj.name);
},0);

构造函数中的 this 指向
五、作为构造函数调用
例如 new Foo();
先来看一个简单的例子:
var name = 'name1';
function Foo(){
// 赋值this(当前对象)的name属性值
this.name = 'name2';
}
// new 构造函数产生一个实例
var foo = new Foo();
console.log(name);
console.log(foo.name);
// 直接调用该函数
Foo();
console.log(name);

可以看到,如果函数倾向于与 new 关键字一起使用,则称该函数为构造函数。当使用 new 调用后,this 指向新创建的对象(这个过程也涉及继承机制)。
若直接调用该函数,this 则默认指向全局对象。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。
怎么用 Promise 封装 JavaScript sleep 函数实现异步延时
2026-11-05 17:49:14
什么时候该用JS构造器:与工厂模式、字面量的选择对比
2026-11-05 16:18:22
推荐几款轻量级JS照片墙开源库及对比
2026-11-05 15:56:19
JavaScript递归写法有哪些常见陷阱及避免方法
2026-11-05 14:53:38
JS数组浅拷贝与深拷贝怎么选?场景与方法总结
2026-11-05 14:41:02
