详解JavaScript中的this指向问题

作者:代码拾荒

时间:2026-10-24

浏览:303

本文深入解析JavaScript中this关键字的指向规则。通过默认调用、对象方法调用、构造函数及定时器等多种场景示例,阐明this在函数定义时不确定、执行时确定的核心原则,并介绍bind、call、apply改变this指向的方法,帮助开发者彻底掌握this的使用逻辑。

文章目录

题记

在JavaScript开发中,this的指向规则往往是初学者面临的难点。本文将详细梳理this的指向原则,通过具体案例解析其工作机制,帮助读者彻底厘清这一概念,避免在实际编码中因this指向错误而产生困扰。

开篇

首先明确,this是JavaScript语言中的一个关键字。

它代表函数运行时自动生成的一个内部对象,且仅在函数内部可用。随着函数使用场景的不同,this的值也会随之变化。核心原则在于:this的指向在函数定义阶段无法确定,只有在函数执行时才能明确其指向。实际上,this最终指向的是调用该函数的对象。接下来,我们将通过逐步探索来深入理解这一机制。

探索一


function a() {
  var user = "清蒸胖头鱼";
  console.log(this.name); //undefined
  console.log(this); //Window
 }
 a();
 window.a();//两种结果相同

根据前述原则,this最终指向调用其所在函数的对象。在示例中,函数a是由全局对象window通过点操作符调用的,因此这里的this指向window对象。

探索二


var obj = {
  name: '清蒸胖头鱼',
  f1: function () {
   console.log(this.name);//清蒸胖头鱼
  }
 };
 obj.f1();

再次强调,this的指向在函数定义时是不确定的,仅在函数执行时确定。在示例中,函数f1由对象obj调用,因此此时的this指向obj对象。

探索三

为了彻底理解this的机制,我们需要分析后续的几个典型示例。


var obj = {
  a: 5,
  b: {
   a: 10,
   fn: function () {
    console.log(this.a); //10
   }
  }
 };
 obj.b.fn();

既然原则指出this指向调用其所在函数的对象,为何在示例中并未指向obj对象?

此处需要补充三个关键判断逻辑:

  1. 若函数内部包含this,但该函数未被上一级对象调用,则this指向window。
  2. 若函数内部包含this,且该函数被上一级对象调用,则this指向该上一级对象。
  3. 若函数内部包含this,且该函数涉及多个对象层级,即使由最外层对象调用,this仍指向直接调用它的上一级对象。

至此,相信读者已基本掌握this指向的核心原则:this在函数定义时不确定,仅在执行时确定,最终指向调用该函数的对象。

下面介绍this在不同使用场景下的具体表现。

构造函数(使用new关键字)的情况


function Student() {
  this.name = '清蒸胖头鱼';
 }
 var s1 = new Student();
 console.log(s1.name);// 清蒸胖头鱼

对象s1能够访问函数Student内部的name属性,是因为new关键字改变了this的指向,使其指向新创建的对象s1。


// new 关键字执行的过程
 1. 在函数体内创建一个空的对象.
 2. 让当前this指向这个空的对象.
 3. 通过this给当前空的对象添加键值对.
 4. 返回已经添加好所有键值对的对象给外面的变量.

定时器中的this指向情况


var num = 0;
 function Obj() {
  this.num = 1;
  this.getNum1 = function () {
   console.log(this.num);
  };
  this.getNum2 = function () {
   setInterval(function () {
    console.log(this.num);
   }, 1000);
  };
 }
 var o = new Obj();
 o.getNum1();//1  (o.num)
 o.getNum2();//0 (window.num)

o.getNum2()的值之所以为0,即这里的this指向window。再次应用this指向原则:this的指向在函数定义时不确定,只有函数执行时才能确定this指向谁,实际上this最终指向调用其所在函数的对象。

解: this.num所在的函数为定时器setInterval内的function () { console.log(this.num);},根据this指向原则当该函数被执行,this指向它的上一级对象。setInterval,又因setInterval是window点出了的,所以this指向window。

call、apply、bind 改变指向情况


var num = 0;
 function Obj() {
  this.num = 1;
  this.getNum1 = function () {
   console.log(this.num);
  };
  this.getNum2 = function () {
   setInterval(function () {
    console.log(this.num);
   }.bind(this), 1000);//利用bind将this绑定到这个函数上
  };
 }
 var o = new Obj();
 o.getNum1();//1  (o.num)
 o.getNum2();//1 (o.num)
 

解释:

bind()方法是Function.prototype上的一个方法。当被绑定函数调用时,bind方法会创建一个新函数,并将第一个参数作为新函数运行时的this。

根据原则:

未使用bind方法前:被调用时,this.num指向调用其所在函数的对象,即window.setTimeout对象。使用bind方法后:被调用时,将原来的this重新指向→调用getSum2函数(即新this所在的函数)的对象。此处通过构造函数new调用,因此指向o对象。

bind方法在此类场景中较为常用。当然,使用call或apply方法替代也能得到正确结果,但call和apply方法会在调用后立即执行,从而失去延时的效果,使得定时器失去意义。

以上即为详解JavaScript中this指向问题的详细内容,更多关于JavaScript this指向的资料请关注本站其它相关文章!

实用工具推荐

电子包浆

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

使用 ›
图片压缩

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

使用 ›
相关文章