当前位置: 首页 > web >正文

改变this指向的方法

文章目录

  • 一、为什么要改变 this 的指向?
  • 二、如何改变 this 的指向?
    • 1. bind() -- 返回一个绑定了 this 的新函数
    • 2. call()和apply() -- 立即调用函数并指定this
    • 3. 箭头函数 -- 不绑定 this,继承外层作用域
    • 4. 临时变量保存 this (旧写法)
  • 三、各种方法的区别与对比
  • 四、项目中实践
    • 1. 表单校验中的回调(Vue/React 常见)
    • 2. React Class 组件中绑定事件
    • 3. Vue 2.x 汇总使用定时器或者第三方库回调
    • 4. 数组方法中的回调函数
  • 五、总结

一、为什么要改变 this 的指向?

在 JavaScript 中,this 是一个经常让初学者头疼的问题,尤其是在函数调用、事件处理、回调函数等场景中。this的指向经常“不按套路出牌”。因此,掌握并合理改变this的指向,对于写出高质量的 JavaScript 代码至关重要。

示例1: 回调函数中丢失 this

const person = {name: "HopeBearer",greet() {setTimeout(function() {console.log(`Hello, I am ${this.name}`)}, 1000)}
}person.greet() // => Hello, I am undefined

this 指向了 window,不是person,原因是在浏览器中,普通函数默认的this是window对象(在严格模式下是undefined),因此,this.name 实际上是 window.name,而浏览器环境中默认 window.name 是undefined。

示例2:事件处理函数中 this 指向DOM元素

const btn = document.querySelector('#btn')
const app = {text: 'Click me!',handleClick() {console.log(this.text)}
}
btn.addEventListener('click', app.handleClick); // => undefined

this 实际指向的是触发事件的 DOM 元素,而不是 app,原因是app.handleClick 是一个方法,它直接作为回调传给了addEventListener,在这种情况下,JavaScript 并不会保留 app 作为 this,而是将 this 设置为触发事件的 DOM 元素。

二、如何改变 this 的指向?

JavaScript 提供了多种方式来控制 this,包括:bind、call、apply、箭头函数、临时变量等。

1. bind() – 返回一个绑定了 this 的新函数

const boundFn = app.handleClick.bind(app)
btn.addEventListener('click', boundFn)

2. call()和apply() – 立即调用函数并指定this

function sayHello(age) {console.log(`Hello, I am ${this.name}, ${age} years old.`)
}const person = {name: 'Bob'
}
sayHello.call(person, 30) // 参数用逗号分隔
sayHello.apply(person, [30]) // 参数用数组

3. 箭头函数 – 不绑定 this,继承外层作用域

const person = {name: 'HopeBearer',greet() {setTimeout(() => {console.log(`Hello, I am ${this.name}`)}, 1000)}
}person.greet() // Hello, I am HopeBearer

4. 临时变量保存 this (旧写法)

const self = this;
setTimeout(function(){console.log(self.name)
}, 1000)

三、各种方法的区别与对比

方法是否立即调用是否返回新函数是否永久绑定是否继承作用域使用场景
call()✅ 是❌ 否❌ 否❌ 否临时调用函数,改变上下文
apply()✅ 是❌ 否❌ 否❌ 否参数为数组时调用函数
bind()❌ 否✅ 是✅ 是❌ 否创建新函数,延迟调用
箭头函数✅ 自动❌ 否✅ 是(不可更改)✅ 是回调函数、计时器、事件等保留 this
临时变量法❌ 否❌ 否✅ 是✅ 是老写法(可用箭头函数替代)

四、项目中实践

1. 表单校验中的回调(Vue/React 常见)

form.validateField('username', function(isValid) {if(isValid) {this.submitForm()}
}).bind(this) //  显式绑定

2. React Class 组件中绑定事件

class MyComponent extends React.Component {constructor(props) {super(props);this.handleClick = this.handleClick.bind(this) // 提前绑定}handleClick(){console.log(this.props.title)}render() {return <button onClick={this.handleClick}>Click</button>}
}//  React 函数组件可用箭头函数或 useCallback

3. Vue 2.x 汇总使用定时器或者第三方库回调

export default {methods: {loadData() {setTimeout(() => {this.fetchData(); // 箭头函数保留 this}, 1000);}}
}

4. 数组方法中的回调函数

const people = ['Alice', 'Bob'];
const greeter = {prefix: 'Hello',greetAll() {people.forEach(function(name) {console.log(`${this.prefix}, ${name}`);}.bind(this)); // 显式绑定 this}
};
greeter.greetAll();

五、总结

JavaScript 中的 this 是一个灵活而强大的机制,但也极易出错。掌握以下要点,能让你写出更可靠的代码:

  • call/apply 用于立即调用函数;

  • bind 用于返回一个永久绑定 this 的函数;

  • 箭头函数则用于保留父作用域的 this,尤其适合回调;

  • 在 Vue/React 项目中合理选择方式,避免 this 丢失带来的问题。

http://www.xdnf.cn/news/14986.html

相关文章:

  • 前端环境nvm/pnpm下载配置
  • Modbus TCP 通信多请求处理
  • c++对象池
  • .golangci.yml文件配置
  • 【大模型入门】访问GPT_API实战案例
  • 数据挖掘:深度解析与实战应用
  • 谷歌浏览器安全输入控件-allWebSafeInput控件
  • 深度学习6(多分类+交叉熵损失原理+手写数字识别案例TensorFlow)
  • Android 应用开发 | 一种限制拷贝速率解决因 IO 过高导致系统卡顿的方法
  • C#使用Qdrant实现向量存储及检索
  • 内存池(C++)v1
  • CICD[导航]、docker+gitlab+harbor+jenkins从安装到部署
  • .NET9 实现字符串拼接(StringConcatenation)性能测试
  • 【机器学习笔记 Ⅱ】2 神经网络中的层
  • ch03 部分题目思路
  • 深入探索 pnpm:高效磁盘利用与灵活的包管理解决方案
  • 深度学习篇---简单果实分类网络
  • 软件工程中耦合度
  • 如何正确规范的开发术语自己的TYPECHO插件
  • 条件渲染 v-show与v-if
  • Web开发安全 之 信息加密
  • Spring Boot 集成 Thymeleaf​​ 的快速实现示例,无法渲染页面问题解决
  • 基于Flask和机器学习开发的米其林餐厅数据可视化平台
  • Peek-Ubuntu上Gif录制工具-24.04LTS可装
  • ClickHouse 全生命周期性能优化
  • Java零基础笔记01(JKD及开发工具IDEA安装配置)
  • 数据库学习笔记(十七)--触发器的使用
  • Chat Model API
  • centos 7.6安装mysql8
  • MySQL GROUP_CONCAT函数实现列转行