JS传统函数中常见的 this 绑定问题
在 JavaScript 中,传统函数的 this 绑定规则依赖于函数的调用方式,这常常导致一些意外的行为和常见的 this 绑定问题。以下是一些典型的 this 绑定问题及其解决方案。
1. 作为对象方法调用时的 this 丢失
当一个对象的方法被赋值给一个变量或作为回调函数传递时,this 的值可能会丢失,导致 this 指向全局对象或 undefined(在严格模式下)。
示例
const obj = {name: 'Alice',greet: function() {console.log(`Hello, ${this.name}!`);}
};const greet = obj.greet;
greet(); // 输出: Hello, undefined! (因为 this 指向全局对象)
解决方案
-
使用
bind方法:可以使用bind方法来显式地绑定this。const obj = {name: 'Alice',greet: function() {console.log(`Hello, ${this.name}!`);} };const greet = obj.greet.bind(obj); greet(); // 输出: Hello, Alice! -
使用箭头函数:箭头函数没有自己的
this绑定,会继承其词法作用域中的this。const obj = {name: 'Alice',greet: function() {console.log(`Hello, ${this.name}!`);} };const greet = () => obj.greet(); greet(); // 输出: Hello, Alice!
2. 在回调函数中 this 的值不正确
在使用定时器、事件监听器或其他异步操作时,回调函数中的 this 可能会指向错误的对象。
示例
const obj = {name: 'Alice',greet: function() {setTimeout(function() {console.log(`Hello, ${this.name}!`); // 这里的 this 指向全局对象}, 1000);}
};obj.greet(); // 1秒后输出: Hello, undefined!
解决方案
-
使用
bind方法:可以使用bind方法来显式地绑定this。const obj = {name: 'Alice',greet: function() {setTimeout(function() {console.log(`Hello, ${this.name}!`);}.bind(this), 1000);} };obj.greet(); // 1秒后输出: Hello, Alice! -
使用箭头函数:箭头函数没有自己的
this绑定,会继承其词法作用域中的this。const obj = {name: 'Alice',greet: function() {setTimeout(() => {console.log(`Hello, ${this.name}!`);}, 1000);} };obj.greet(); // 1秒后输出: Hello, Alice!
3. 作为构造函数调用时的 this 问题
虽然构造函数中的 this 通常指向新创建的实例对象,但在某些情况下,如果不使用 new 关键字调用构造函数,this 会指向全局对象。
示例
function Person(name) {this.name = name;
}const p = Person('Bob'); // 忘记使用 new 关键字
console.log(p); // undefined
console.log(window.name); // 输出: Bob
解决方案
-
检查
new.target:可以使用new.target来检测函数是否作为构造函数调用。function Person(name) {if (!new.target) {throw new Error('Person must be called with new');}this.name = name; }try {const p = Person('Bob'); // 抛出错误: Person must be called with new } catch (e) {console.error(e.message); }const p2 = new Person('Bob'); // 正确调用 console.log(p2.name); // 输出: Bob
4. 在事件处理程序中 this 的值不正确
在事件处理程序中,this 通常指向触发事件的元素,而不是预期的对象。
示例
const button = document.createElement('button');
button.textContent = 'Click me';
document.body.appendChild(button);const obj = {name: 'Alice',handleClick: function(event) {console.log(`Button clicked by ${this.name}`); // 这里的 this 指向按钮元素}
};button.addEventListener('click', obj.handleClick);
解决方案
-
使用
bind方法:可以使用bind方法来显式地绑定this。const button = document.createElement('button'); button.textContent = 'Click me'; document.body.appendChild(button);const obj = {name: 'Alice',handleClick: function(event) {console.log(`Button clicked by ${this.name}`);} };button.addEventListener('click', obj.handleClick.bind(obj)); -
使用箭头函数:箭头函数没有自己的
this绑定,会继承其词法作用域中的this。const button = document.createElement('button'); button.textContent = 'Click me'; document.body.appendChild(button);const obj = {name: 'Alice',handleClick: () => {console.log(`Button clicked by ${this.name}`);} };button.addEventListener('click', obj.handleClick);
5. 在类方法中 this 的值不正确
在类方法中,如果方法被赋值给一个变量或作为回调函数传递,this 的值可能会丢失。
示例
class Person {constructor(name) {this.name = name;}greet() {console.log(`Hello, ${this.name}!`);}
}const person = new Person('Alice');
const greet = person.greet;
greet(); // 输出: Hello, undefined! (因为 this 指向全局对象)
解决方案
-
使用
bind方法:可以在构造函数中使用bind方法来显式地绑定this。class Person {constructor(name) {this.name = name;this.greet = this.greet.bind(this);}greet() {console.log(`Hello, ${this.name}!`);} }const person = new Person('Alice'); const greet = person.greet; greet(); // 输出: Hello, Alice! -
使用箭头函数:可以在类方法中使用箭头函数来避免
this绑定问题。class Person {constructor(name) {this.name = name;}greet = () => {console.log(`Hello, ${this.name}!`);} }const person = new Person('Alice'); const greet = person.greet; greet(); // 输出: Hello, Alice!
总结
传统函数中的 this 绑定问题主要集中在以下几个方面:
1. 作为对象方法调用时的 this 丢失:可以通过 bind 方法或箭头函数解决。
2. 在回调函数中 this 的值不正确:可以通过 bind 方法或箭头函数解决。
3. 作为构造函数调用时的 this 问题:可以通过检查 new.target 来解决。
4. 在事件处理程序中 this 的值不正确:可以通过 bind 方法或箭头函数解决。
5. 在类方法中 this 的值不正确:可以通过 bind 方法或箭头函数解决。
理解这些常见的 this 绑定问题及其解决方案,可以帮助你编写更可靠和维护性更好的代码。
相关文章:
JS传统函数中常见的 this 绑定问题
在 JavaScript 中,传统函数的 this 绑定规则依赖于函数的调用方式,这常常导致一些意外的行为和常见的 this 绑定问题。以下是一些典型的 this 绑定问题及其解决方案。 1. 作为对象方法调用时的 this 丢失 当一个对象的方法被赋值给一个变量或作为回调函…...
跨域问题以及使用vscode的LiveServer插件跨域访问
目录 现象跨域问题的定义(文心一言)解决办法同源部署后端代理VS Code LiveServer 现象 以下前端代码部署后,在网页访问时报错:No ‘Access-Control-Allow-Origin’ header is present on the requested resource. $.ajax({url:…...
现代Web开发:WebSocket 实时通信详解
💓 博客主页:瑕疵的CSDN主页 📝 Gitee主页:瑕疵的gitee主页 ⏩ 文章专栏:《热点资讯》 现代Web开发:WebSocket 实时通信详解 现代Web开发:WebSocket 实时通信详解 现代Web开发:WebS…...
《深度学习》——深度学习基础知识(全连接神经网络)
文章目录 1.神经网络简介2.什么是神经网络3.神经元是如何工作的3.1激活函数3.2参数的初始化3.2.1随机初始化3.2.2标准初始化3.2.3Xavier初始化(tf.keras中默认使用的)3.2.4He初始化 4.神经网络的搭建4.1通过Sequential构建神经网络4.2通过Functional API…...
nginx 部署2个相同的vue
起因: 最近遇到一个问题,在前端用nginx 部署 vue, 发现如果前端有改动,如果不适用热更新,而是直接复制项目过去,会404 因此想到用nginx 负载两套相同vue项目,然后一个个复制vue项目就可以了。…...
利用Java easyExcel库实现高效Excel数据处理
在Java应用程序中,处理Excel文件是一项常见任务,尤其是在需要读取、写入或分析大量数据时。easyExcel是一个基于Java的高性能Excel处理库,它提供了简洁的API和优化的性能,以简化Excel文件的处理。本文将指导您如何使用easyExcel库…...
Vulnhub靶场 Metasploitable: 1 练习(上)
目录 0x00 准备0x01 主机信息收集0x02 Samba服务(CVE-2007-2447)0x03 Distccd(CVE-2004-2687)0x04 Mysql弱口令0x05 Postgresql弱口令0x06 Telnet弱口令0x07 Tomcat 0x00 准备 下载链接:https://download.vulnhub.com/…...
《Python编程实训快速上手》第二天--列表与元组
一、列表 1、理解 列表是一个值,包含由多个值构成的序列 2、元素查找 1)索引--取列表中的单个值 正数索引:同c语言中的数组 spam [[1,2,3,4],["cat","dog"]] print(spam[0][1]) #结果:2 负数索引&…...
jangow靶机
先改jangow的ip设置,无ip地址,重启jangow虚拟机时候快速按E这个键盘,进入到编辑模式,找到ro这个位置,写入ro rw signin init/bin/bash ,ctrlx保存 下一步需要更改网卡名字为ens33,可以直接…...
使用UDP协议传输视频流!(分片、缓存)
背景 最近在开发工作中遇到需要两台本地设备之间进行视频流的传输的情况。但是团队一来没有这方面的专业人才,二来视频流的传续数据量很大,针对TCP和UDP的具体选择也不明确。 本文是在上诉背景之下进行的研究和开发工作。 目录 背景 UDP和TCP协议的…...
Pinia小菠萝(状态管理器)
Pinia 是一个专为 Vue 3 设计的状态管理库,它借鉴了 Vuex 的一些概念,但更加轻量灵活。下面将详细介绍如何使用 Pinia 状态管理库: 安装 Pinia 使用 npm:在项目目录下运行npm install pinia。使用 yarn:在项目目录下运…...
Python知识点:基于Python工具,如何使用Web3.py进行以太坊智能合约开发
开篇,先说一个好消息,截止到2025年1月1日前,翻到文末找到我,赠送定制版的开题报告和任务书,先到先得!过期不候! 基于Python工具Web3.py进行以太坊智能合约开发 简介 智能合约是区块链技术的核…...
【简信CRM-注册安全分析报告】
前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 暴力破解密码,造成用户信息泄露短信盗刷的安全问题,影响业务及导致用户投诉带来经济损失,尤其是后付费客户,风险巨大,造成亏损无底洞…...
ssm+vue694基于Java的药店药品信息管理系统的设计与实现
博主介绍:专注于Java(springboot ssm 等开发框架) vue .net php phython node.js uniapp 微信小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设,从业十五余年开发设计教学工作 ☆☆☆ 精彩专栏推荐订阅☆☆☆☆☆不…...
Sentinel微服务保护
目录 雪崩问题 解决雪崩问题的方法: 我们使用sentinel组件实现微服务的保护 一:下载sentinel 二.启动sentinel 三.访问:localhost:8080 默认的账号和密码都是sentinel 微服务整合sentinel 一.导入sentinel依赖 二.在application.yml配置…...
喜讯!实在Agent智能体入选《2024年度最佳企业服务AI产品榜》
10 月 30 日,硅星人主办的首届 AI 创造者大会(ACC)于北京中关村盛大举行。此次大会旨在为 AI 产业生态的共建者构筑一个多元化的交流平台。大会邀请了硅星人创始人兼 CEO 骆轶航、国家地方共建具身智能机器人创新中心 CTO 唐剑、百度智能云应…...
Aop+自定义注解实现数据字典映射
数据字典 Web项目开发中,字典表的一般都会存在,主要用来给整个系统提供基础服务。 比如男女性别的类型可以使用0和1来进行表示,在存储数据和查询数据的时候,就可以使用字典表中的数据进行翻译处理。 再比如之前做的一个项目中宠物…...
大语言模型(LLM)入门级选手初学教程 III
指令微调 一、指令数据的构建 包括任务描述(也称为指令)、任务输入-任务输出以及可选的示例。 Self-Instruct 指令数据生成:从任务池中随机选取少量指令数据作为示例,并针对Chat-GPT 设计精细指令来提示模型生成新的微调数据…...
STM32G0xx使用LL库将Flash页分块方式存储数据实现一次擦除可多次写入
STM32G0xx使用LL库将Flash页分块方式存储数据实现一次擦除可多次写入 参考例程例程说明一、存储到Flash中的数据二、Flash最底层操作(解锁,加锁,擦除,读写)三、从Flash块中读取数据五、测试验证 参考例程 STM32G0xx HAL和LL库Flash读写擦除操…...
SAP B1 认证考试习题 - 解析版(三)
前一篇:《SAP B1 认证考试习题 - 解析版(二)》 题目纯享版合集:《SAP B1 认证考试习题 - 纯享版》 五、运费(附加费用) 57. 以下哪个选项能够影响库存商品的价格 A. 仅为总量级别的附加费用 B. 只为行级…...
ipmitool实战指南:从基础命令到高级服务器管理技巧
1. 初识ipmitool:服务器管理的瑞士军刀 第一次接触ipmitool是在五年前的一个深夜,当时机房有台服务器突然失去响应,运维同事却在外地出差。正当大家束手无策时,老张轻描淡写地说了句"用IPMI啊",然后在笔记本…...
WMIC命令行高效卸载Windows软件:从入门到精通
1. 为什么选择WMIC卸载软件? 每次电脑卡顿的时候,打开C盘一看,总会被各种不明所以的软件占满空间。传统的卸载方式要经过"控制面板-程序和功能-找到目标-点击卸载"的繁琐流程,而WMIC只需要几行命令就能搞定。我在帮同事…...
OpenClaw技能扩展指南:为Phi-3-mini-128k-instruct添加Markdown转换能力
OpenClaw技能扩展指南:为Phi-3-mini-128k-instruct添加Markdown转换能力 1. 为什么需要文档处理技能? 上周我整理技术文档时遇到了一个典型问题:收到同事发来的PDF技术白皮书,需要提取关键章节并转换为Markdown格式存档。手动操…...
translategemma-27b-it部署案例:个人开发者用RTX4060实现本地化翻译服务
translategemma-27b-it部署案例:个人开发者用RTX4060实现本地化翻译服务 1. 为什么这个模型值得你花10分钟试试? 你有没有过这样的时刻: 看到一篇技术文档的截图,但图片里的中文说明没法直接复制翻译;收到朋友发来的…...
MegSpot专业视觉分析工具:从基础操作到高级应用全指南
MegSpot专业视觉分析工具:从基础操作到高级应用全指南 【免费下载链接】MegSpot MegSpot是一款高效、专业、跨平台的图片&视频对比应用 项目地址: https://gitcode.com/gh_mirrors/me/MegSpot 在数字媒体创作与分析领域,如何高效对比图片细节…...
5分钟搭建原神私服:KCN-GenshinServer终极指南
5分钟搭建原神私服:KCN-GenshinServer终极指南 【免费下载链接】KCN-GenshinServer 基于GC制作的原神一键GUI多功能服务端。 项目地址: https://gitcode.com/gh_mirrors/kc/KCN-GenshinServer 还在为复杂的命令行配置而头疼吗?想要轻松拥有自己的…...
MT管理器安卓版,APK逆向修改神器,APP提取APK教程。
今天算是比较郁闷的一天,作为互联网上算是最老的一批写用户,如果你是带人学习互联网的大佬,估计你都会放弃我这种年龄段的人,不过我还是活下来了,像我们这样的80、90后还有一大批活下来了。 AI出来了给人的引影响很大…...
EcomGPT-7B模型文件结构与代码解读:从Hugging Face到生产部署
EcomGPT-7B模型文件结构与代码解读:从Hugging Face到生产部署 如果你已经玩过一些开箱即用的AI模型,可能会好奇,一个像EcomGPT-7B这样的模型,它到底是由哪些文件组成的?那些配置文件里密密麻麻的参数都是什么意思&…...
Vite+Vue3多页面项目实战:动态配置入口与多环境变量管理
1. 为什么需要多页面应用架构 最近接手了一个中后台管理系统重构项目,遇到了一个典型场景:系统包含客服工单和数据分析两个完全独立的模块,它们共享相同的UI组件库和用户认证体系,但业务逻辑完全没有交集。这种场景下,…...
PyTorch 2.8多场景实操:科研训练+工程推理+内容创作的统一技术底座
PyTorch 2.8多场景实操:科研训练工程推理内容创作的统一技术底座 1. 为什么选择PyTorch 2.8作为统一技术底座 PyTorch 2.8作为当前最主流的深度学习框架之一,已经成为学术界和工业界的首选工具。这个基于RTX 4090D 24GB显卡深度优化的镜像,…...
