JavaScript中this指向的四种核心场景解析

作者:代码拾荒时间:2026-10-22 06:17:57浏览:588

本文系统总结JavaScript中this的四种核心指向规则:全局变量挂载于window、普通函数指向调用者、构造函数指向实例以及箭头函数继承外层this。通过非严格模式、严格模式、对象方法、事件处理及call/apply/bind等场景的代码示例,深入解析this绑定机制及常见设计缺陷的规避方案。

JavaScript this指向的核心规则概述

在JavaScript开发中,this的指向机制常令前端开发者感到困惑,也是各类面试中的高频考点。为了厘清这一概念,我们需要先掌握几个基础定义。

第一,全局变量默认挂载在window对象之下。

第二,通常情况下,this指向其直接调用者。

第三,在ES6的箭头函数中,this指向定义时的外层作用域(即创建者),而非调用者。

第四,可以通过call、apply和bind方法人为改变函数的this指向。

接下来,我们将结合具体场景对上述规则进行详细分析。

普通函数调用中的this指向

场景一:普通函数调用

在非严格模式下:


const func = function () {
  console.log(this);
  const func2 = function () {
   console.log(this);
  };
  func2(); //Window
 };
 func(); //Window

在严格模式下:


'use strict'
 const func = function () {
  console.log(this);
  const func2 = function () {
   console.log(this);
  };
  func2(); //undefined
 };
 func(); //undefined

结合上述规则一和规则四分析:func函数属于全局函数,默认挂载在window对象上,因此this指向调用者window,输出window对象。但在严格模式下,this不允许指向全局变量window,因此输出为undefined。func2在函数内部直接调用时,默认指向全局window,这被视为JavaScript设计上的一个缺陷。理想的设计应是内部函数的this绑定到其外层函数对应的对象上。为规避此缺陷,JavaScript程序员通常采用变量替代的方法,约定将this赋值给that变量,该方式将在后续内容中提及。

对象方法调用中的this指向

场景二:作为对象方法调用


const user = {

  userName: '小张',
  age: 18,
  selfIntroduction: function () {
   const str = '我的名字是:' + this.userName + ",年龄是:" + this.age;
   console.log(str);

   const loop = function () {
    console.log('我的名字是:' + this.userName + ",年龄是:" + this.age);
   };

   loop();  //我的名字是:undefined,年龄是:undefined

  }
 };

 user.selfIntroduction(); //我的名字是:小张,年龄是:18

根据规则一,this指向其调用者。在selfIntroduction()方法中,调用者为user,因此方法内部的this指向父对象user。而loop方法输出undefined的原因,正是前文所述的JavaScript设计缺陷。针对这种情况,通常的做法是在selfIntroduction()方法内部将this缓存下来。


const user = {
  userName: '小张',
  age: 18,
  selfIntroduction: function () {
   const str = '我的名字是:' + this.userName + ",年龄是:" + this.age;
   console.log(str);

   const that=this;

   const loop = function () {
    console.log('我的名字是:' + that.userName + ",年龄是:" + that.age);
   };

   loop();  //我的名字是:小张,年龄是:18

  }
 };

 user.selfIntroduction(); //我的名字是:小张,年龄是:18

此时,loop方法中的this指向便符合预期。


const user={

  userName:'小张',
  age:18,
  selfIntroduction:function(){
   const str='我的名字是:'+this.userName+",年龄是:"+this.age;
   console.log(str); 
  }
 };

 const other =user.selfIntroduction;
 other(); //我的名字是:undefined,年龄是:undefined

 const data={
  userName:'小李',
  age:19,
 };
 data.selfIntroduction=user.selfIntroduction;
 data.selfIntroduction(); //我的名字是:小李,年龄是:19

观察这段代码:将selfIntroduction()赋值给全局变量other,调用other()时,other挂载在全局window对象下。由于window对象上没有userName和age属性,因此输出undefined。在第二段代码中,声明了包含username和age属性的data对象。依据规则二,this通常指向调用者,此处data是selfIntroduction()的调用者,因此输出了data的userName和age。

事件处理中的this指向

场景三:在HTML中作为事件触发


<body>

 <div id="btn">点击我</div>

</body>

const btn=document.getElementById('btn');

  btn.addEventListener('click',function () {
   console.log(this); //<div id="btn">点击我</div>
  })

这种情况同样遵循规则二,this指向事件的源对象,即event目标元素。

构造函数与箭头函数的this指向

场景四:使用new关键字(构造函数)


const fun=function(userName){
  this.userName=userName;
 }

 const user=new fun('郭德纲'); 

 console.log(user.userName); //郭德纲

此处不再赘述,new关键字构造了一个对象实例并赋值给user,因此userName成为user对象的属性。

场景五:ES6箭头函数


const func1=()=>{

  console.log(this); 

 };

 func1(); //Window

const data={
  userName:'校长',
  selfIntroduction:function(){
   console.log(this); //Object {userName: "校长", selfIntroduction: function}

   const func2=()=>{
    console.log(this); //Object {userName: "校长", selfIntroduction: function}
   }

   func2();
  }

 }

 data.selfIntroduction();

回顾开头提到的规则三:在ES6箭头函数中,this指向创建者而非调用者。fun1在全局函数下创建,因此this指向全局window;而fun2在对象data下创建,this指向data对象。因此,在func2函数内部,this指向data对象。个人认为,ES6箭头函数的this指向机制是对前述JavaScript设计缺陷的一种改进(个人见解)。

使用call、apply和bind改变this指向

场景六:改变this的指向

call、apply和bind这三个方法可以人为地改变函数的this指向。关于三者的具体区别,将在后续博客中详细解释。此处仅举一例说明。


const func=function(){
 console.log(this);
};

func(); //window

func.apply({userName:"郭德纲"}); //Object {userName: "郭德纲"}

这三种方法均可改变this指向,区别在于:call和apply在绑定this后立即执行该方法,而bind方法返回一个可执行的函数。

综上所述,核心要点即开头提到的四点。

1:全局变量默认挂载在window对象下

2:一般情况下this指向它的调用者

3:es6的箭头函数中,this指向创建者,并非调用者

4:通过call、apply、bind可以改改变this的指向

首次撰写此类技术博客,内心难免忐忑,担心内容是否正确或无人阅读。如有不足之处,欢迎指正。

以上关于JavaScript this指向的总结即为全部内容,希望能提供参考,也希望大家多多支持本站。

作者最新文章