当前位置: 首页 > 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. 只为行级…...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

【Linux】shell脚本忽略错误继续执行

在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...

【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密

在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...