JavaScript中this关键字的五种指向场景详解

作者:闭包旅人

时间:2026-10-31

浏览:624

本文详细解析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);

JavaScript this 指向概览

普通函数调用中的 this

二、函数调用

直接调用一个函数时,this 默认指向全局对象(浏览器端为 window)。


var name = 'name1';
function sayName(){
 console.log(name);
 console.log(this);
}

sayName();
window.sayName();

可以看到

JavaScript this 指向概览

还有一些常见情况,根据“谁调用方法就指向谁”的原则,需要仔细分析 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);

JavaScript this 指向概览

对于类似匿名函数的情况,默认情况下它们是被全局对象(浏览器下的 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);


JavaScript this 指向概览

构造函数中的 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);

JavaScript this 指向概览

可以看到,如果函数倾向于与 new 关键字一起使用,则称该函数为构造函数。当使用 new 调用后,this 指向新创建的对象(这个过程也涉及继承机制)。

若直接调用该函数,this 则默认指向全局对象。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

实用工具推荐

电子包浆

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

使用 ›
图片压缩

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

使用 ›
相关文章