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

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 指向全局对象)
解决方案
  1. 使用 bind 方法:可以使用 bind 方法来显式地绑定 this

    const obj = {name: 'Alice',greet: function() {console.log(`Hello, ${this.name}!`);}
    };const greet = obj.greet.bind(obj);
    greet(); // 输出: Hello, Alice!
  2. 使用箭头函数:箭头函数没有自己的 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!
解决方案
  1. 使用 bind 方法:可以使用 bind 方法来显式地绑定 this

    const obj = {name: 'Alice',greet: function() {setTimeout(function() {console.log(`Hello, ${this.name}!`);}.bind(this), 1000);}
    };obj.greet(); // 1秒后输出: Hello, Alice!
  2. 使用箭头函数:箭头函数没有自己的 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
解决方案
  1. 检查 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);
解决方案
  1. 使用 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));
  2. 使用箭头函数:箭头函数没有自己的 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 指向全局对象)
解决方案
  1. 使用 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!
  2. 使用箭头函数:可以在类方法中使用箭头函数来避免 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. 只为行级…...

【kafka】Golang实现分布式Masscan任务调度系统

要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来&#xf…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

【AI学习】三、AI算法中的向量

在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...

LLM基础1_语言模型如何处理文本

基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...

代码随想录刷题day30

1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...

R语言速释制剂QBD解决方案之三

本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...