JavaScript中的this问题超详细总结

 更新时间:2025年06月05日 10:07:23   作者:言者非也  
这篇文章主要介绍了JavaScript中this问题的相关资料,this的指向规则涵盖全局、对象方法、构造函数、箭头函数及事件处理中的上下文,文中通过代码介绍的非常详细,需要的朋友可以参考下

一、this的指向问题

1、全局环境的this

在全局环境中(即不在任何函数内部),this 指向全局对象:

  • 在浏览器环境中,this 指向 window 对象。
console.log(this); // 浏览器环境中输出 window
  • 在 Node.js 环境中,this 指向 global 对象(但在严格模式下,this 是 undefined)。
"use strict";
console.log(this); // 输出 undefined

2、对象方法中的this

当 this 出现在对象的方法中时,this 指向调用该方法的对象。

const obj = {
  name: 'Alice',
  sayName: function () {
    console.log(this.name);
  }
};

obj.sayName(); // 输出 'Alice'

3、构造函数中的 this

在构造函数中,this 指向正在创建的实例对象。

function Person(name) {
  this.name = name;
}

const person1 = new Person('Bob');
console.log(person1.name); // 输出 'Bob'

4、箭头函数中的this

箭头函数不会创建自己的 this,它会捕获其所在上下文的 this 值。

const obj = {
  name: 'Alice',
  sayName: function () {
    const arrowFunc = () => {
      console.log(this.name);
    };
    arrowFunc();
  }
};

obj.sayName(); // 输出 'Alice'
//箭头函数 arrowFunc 中的 this 继承自 sayName 方法中的 this,即 obj

5、事件处理器中的 this

在 DOM 事件处理器中,this 默认指向触发事件的 DOM 元素

const button = document.querySelector('button');
button.addEventListener('click', function () {
  console.log(this); // 指向 button 元素
});

如果使用箭头函数作为事件处理器,this 将不再指向 DOM 元素,而是继承自外部作用域的 this

const button = document.querySelector('button');
button.addEventListener('click', () => {
  console.log(this); // 指向外部作用域的 this(可能是 window 或 undefined,取决于严格模式)
});

6、 类中的 this

在类中,this 的行为与构造函数类似,指向当前实例对象。

class Person {
  constructor(name) {
    this.name = name;
  }

  sayName() {
    console.log(this.name);
  }
}

const person = new Person('Dave');
person.sayName(); // 输出 'Dave'

二、回调函数中的this问题

this的指向在回调函数中会变得复杂,而this的指向问题也主要集中于回调函数,因为回调函数的this与上下文的调用有关,因此另开一个章节重新进行分析:

1、普通函数作为回调函数

当普通函数被用作回调函数时,this的指向通常取决于调用该函数的对象,而不是定义它的对象。默认情况下,this在非严格模式下指向全局对象(浏览器中是 window),在严格模式下指向 undefined。

function myCallback() {
  console.log(this);
}

const obj = {
  method: function() {
    [1, 2, 3].forEach(myCallback); // myCallback 作为回调函数
  }
};

obj.method();
// 输出:
// 在非严格模式下,输出 window(浏览器环境)
// 在严格模式下,输出 undefined

2、对象方法作为回调函数

如果对象的方法被用作回调函数,this 通常不会指向该对象,除非显式绑定。

const obj = {
  name: 'Alice',
  sayName: function() {
    console.log(this.name);
  }
};

[1, 2, 3].forEach(obj.sayName);
// 输出:
// undefined(因为 this 不再指向 obj)
// 或者报错(如果 this.name 被访问且 this 是 undefined 或 window)

3、 事件处理器中的回调函数

在 DOM 事件处理器中,this默认指向触发事件的 DOM 元素。如果使用箭头函数,this将继承自外部作用域的 this。

const button = document.querySelector('button');

button.addEventListener('click', function() {
  console.log(this); // 指向 button 元素
});

button.addEventListener('click', () => {
  console.log(this); // 指向外部作用域的 this(可能是 window 或 undefined,取决于严格模式)
});

4、async 回调函数中的 this

在 async 函数或 Promise 的回调中,this 的指向与普通函数相同,取决于调用方式。

const obj = {
  name: 'Alice',
  fetchData: async function() {
    const data = await new Promise((resolve) => {
      setTimeout(() => {
        resolve('Data fetched');
      }, 1000);
    });
    console.log(this.name); // 这里的 this 需要正确绑定
  }
};

// 使用箭头函数或 bind 确保 this 指向 obj
obj.fetchData().then(() => {}); // 正常输出 'Alice'

// 如果在另一个上下文中调用 fetchData,需要绑定 this
const fetch = obj.fetchData;
fetch.call(obj); // 或者使用 bind

三、改变this指向的方法

1、把关键字转为变量

案例:

let xiaoming = {
    age: 18,
    introduce: function() {
        setTimeout(function() {
            console.log(this.age)
        }, 1000)
    }
}

xiaoming.introduce();

解决方案:

let xiaoming = {
    age: 18,
    introduce: function() {
        let a = this;          //用一个变量a来储存
        setTimeout(function() {
            console.log(a.age)  //此处变为调用a
        }, 1000)
    }
}

xiaoming.introduce();

2、绑定函数的this

案例:

class MyCom {
    constructor() {
        this.value = 100;
    }
    getValue() {
        return this.value;
    }
}

let mc = new MyCom();
console.log(mc.getValue());  // 结果: 100

如果修改为下面代码:

class MyCom {
    constructor() {
        this.value = 100;
    }
    getValue() {
        return this.value;
    }
}

let btn = {
    value: 200
}

let mc = new MyCom();
btn.getValue = mc.getValue;
console.log(btn.getValue());  // 结果: 200。因为调用者变为了btn

如果希望函数永远指向MyCom的实例对象:

class MyCom {
    constructor() {
        this.value = 100;
        this.getValue = this.getValue.bind(this);
    }
    getValue() {
        return this.value;  //此时this被锁定为MyCom的实例对象
    }
}

let btn = {
    value: 200
}

let mc = new MyCom();
btn.getValue = mc.getValue;
console.log(btn.getValue());  // 结果: 100

bind方法的使用:每个函数本身都有一个bind方法,作用就是用来固定函数的this指向。其不会对函数本身进行任何改造,实际上它会生成一个新的函数并返回(需要我们接收)如下:

function test() {
}

let newTest = test.bind(xiaoming);
newTest();  // this永远指向xiaoming

3、箭头函数(上文有提过)

4、使用call/apply代替bind

案例:

在上面中使用bind太过繁琐,可以使用call/apply解决问题:

总结

到此这篇关于JavaScript中的this问题的文章就介绍到这了,更多相关js this问题总结内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • JS实现拖拽元素时与另一元素碰撞检测

    JS实现拖拽元素时与另一元素碰撞检测

    这篇文章主要为大家详细介绍了JS实现拖拽元素时与另一元素碰撞检测,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-08-08
  • 原生JS实现列表子元素顺序反转的方法分析

    原生JS实现列表子元素顺序反转的方法分析

    这篇文章主要介绍了原生JS实现列表子元素顺序反转的方法,结合实例形式分析了javascript针对dom元素、数组reverse方法、innerHTML方法等列表元素顺序翻转相关操作技巧,需要的朋友可以参考下
    2018-07-07
  • JavaScript实现可动的canvas环形进度条

    JavaScript实现可动的canvas环形进度条

    这篇文章主要介绍了如何利用JavaScript canvas绘制一个可以动的环形进度条。文中的示例代码讲解详细,感兴趣的小伙伴可以动手试一试
    2022-02-02
  • Javascript简单实现面向对象编程继承实例代码

    Javascript简单实现面向对象编程继承实例代码

    这篇文章主要介绍了Javascript简单实现面向对象编程继承实例代码,简单分析了面向对象程序设计的特征与继承的具体实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-11-11
  • 整理Javascript数组学习笔记

    整理Javascript数组学习笔记

    整理Javascript数组学习笔记,之前一系列的文章是跟我学习Javascript,本文就是进一步学习javascript数组,希望大家继续关注
    2015-11-11
  • js实现随机点名程序

    js实现随机点名程序

    这篇文章主要为大家详细介绍了js实现随机点名程序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-11-11
  • js/jquery遍历对象和数组的方法分析【forEach,map与each方法】

    js/jquery遍历对象和数组的方法分析【forEach,map与each方法】

    这篇文章主要介绍了js/jquery遍历对象和数组的方法,结合实例形式分析了数组遍历的forEach,map与each方法常见使用技巧,需要的朋友可以参考下
    2019-02-02
  • 小程序的基本使用知识点(非常全面,推荐!)

    小程序的基本使用知识点(非常全面,推荐!)

    开发一个小程序在如今来讲是较为简单的,但其实还是有很多的知识点需要大家记住,这篇文章主要给大家介绍了关于微信小程序基本使用的相关资料,需要的朋友可以参考下
    2021-06-06
  • 分享10个常见的JavaScript前端手写功能

    分享10个常见的JavaScript前端手写功能

    这篇文章主要分享10个常见的前端手写功能,防抖、节流、深拷贝、异步控制并发数、继承等功能技巧,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-02-02
  • javascript实现抢购倒计时程序

    javascript实现抢购倒计时程序

    这篇文章主要为大家详细介绍了javascript实现抢购倒计时程序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-08-08

最新评论