一文读懂 es6 中class方法中的this绑定
一直以来有这么个疑问? class 的方法中没有自动的绑定this 为什么手动绑定之后,在绑定之后的方法里调用class中的其他的方法(这个方法为什么就能使用this,不也应该是null或者undefined或者window吗) 还是说这就是class的机制?
于是带着这个疑问去寻找答案
在 JavaScript 中,类的方法中的 this 关键字通常会自动绑定到当前实例对象上。然而,当你将一个类的方法提取出来作为独立的函数调用时,this 的绑定就会丢失,变成 undefined(在严格模式下)或全局对象(在非严格模式下),而不是 null。
手动绑定 this 通常使用 bind、call 或 apply 方法来实现。当你手动绑定 this 之后,你实际上是在创建一个新的函数,并且在这个新函数中,this 被固定为你所指定的对象。因此,在绑定之后的方法里调用类中的其他的方法时,this 仍然指向你所绑定的对象,而不是 null。
这是因为当你使用 bind 方法时,bind 会返回一个新的函数,这个新函数中的 this 值会被永久性地绑定到 bind 方法中传入的第一个参数。当你调用这个新函数时,无论是在哪里调用,this 的值都是你绑定的那个对象。
这是 JavaScript 类和对象机制的一部分,确保了在实例方法中调用其他实例方法时,this 能够正确地引用实例对象。如果你在调用方法时不手动绑定 this,而方法是在类之外的地方被调用,那么 this 就不会自动指向类的实例,而是会丢失绑定,这可能会导致 this 指向全局对象或变为 undefined。
因此,手动绑定 this 是为了确保在方法被提取为独立函数之后,依然可以正确地访问类的实例属性和其他方法。
下面是一个简单的例子,展示了如何在类之外的地方调用类的方法,并解释为什么需要手动绑定 this。
class MyClass {
constructor(name) {
this.name = name;
}
greet() {
console.log(`Hello, my name is ${this.name}`);
}
sayGoodbye() {
console.log(`Goodbye, ${this.name}!`);
this.afterGoodbye();
}
afterGoodbye() {
console.log(`After goodbye, ${this.name} is still here.`);
}
}
const myInstance = new MyClass('Alice');
// 正常调用类中的方法
myInstance.greet(); // 输出: Hello, my name is Alice
// 将方法提取到类之外并尝试调用
const extractedGreet = myInstance.greet;
extractedGreet(); // 输出: Hello, my name is undefined
// 手动绑定 this 后再调用
const boundGreet = myInstance.greet.bind(myInstance);
boundGreet(); // 输出: Hello, my name is Alice
// 类中的一个方法在类之外调用另一个方法
myInstance.sayGoodbye(); // 输出: Goodbye, Alice! After goodbye, Alice is still here.
// 将另一个方法提取到类之外并尝试调用
const extractedSayGoodbye = myInstance.sayGoodbye;
extractedSayGoodbye(); // 输出: Goodbye, undefined! TypeError: this.afterGoodbye is not a function
// 手动绑定 this 后再调用
const boundSayGoodbye = myInstance.sayGoodbye.bind(myInstance);
boundSayGoodbye(); // 输出: Goodbye, Alice! After goodbye, Alice is still here.
- MyClass 是一个类,其中包含三个方法:greet、sayGoodbye 和 afterGoodbye。
- myInstance 是 MyClass 的一个实例,初始化时 name 属性被设置为 'Alice'。
- greet 方法正常调用时会输出 Hello, my name is Alice,因为 this 指向 myInstance。
- 当我们将 greet 方法提取到类之外并直接调用时,this 不再指向 myInstance,而是指向全局对象(在非严格模式下)或 undefined(在严格模式下),因此输出 Hello, my name is undefined。
- 使用 bind 方法手动绑定 this 到 myInstance 后,再次调用 greet 方法,this 指向 myInstance,输出 Hello, my name is Alice。
- sayGoodbye 方法在类内部调用 afterGoodbye 方法时,this 正常指向 myInstance,因此输出 Goodbye, Alice! After goodbye, Alice is still here.。
- 当我们将 sayGoodbye 方法提取到类之外并直接调用时,this 不再指向 myInstance,导致 this.name 输出 undefined,并且 this.afterGoodbye 不是一个函数,抛出 TypeError。
- 使用 bind 方法手动绑定 this 到 myInstance 后,再次调用 sayGoodbye 方法,this 指向 myInstance,输出 Goodbye, Alice! After goodbye, Alice is still here.。
通过这个例子,你可以看到手动绑定 this 的重要性,特别是在将方法提取到类之外调用时。
一文读懂 es6 中class方法中的this绑定的更多相关文章
- 一文读懂ES6(附PY3对比)
Ⅰ.ES6~POP¶ 代码示例:https://github.com/lotapp/BaseCode/tree/master/javascript/1.ES6 在线演示:https://githu ...
- 一文读懂高性能网络编程中的I/O模型
1.前言 随着互联网的发展,面对海量用户高并发业务,传统的阻塞式的服务端架构模式已经无能为力.本文(和下篇<高性能网络编程(六):一文读懂高性能网络编程中的线程模型>)旨在为大家提供有用的 ...
- 一文读懂神经网络训练中的Batch Size,Epoch,Iteration
一文读懂神经网络训练中的Batch Size,Epoch,Iteration 作为在各种神经网络训练时都无法避免的几个名词,本文将全面解析他们的含义和关系. 1. Batch Size 释义:批大小, ...
- 一文读懂数仓中的pg_stat
摘要:GaussDB(DWS)在SQL执行过程中,会记录表增删改查相关的运行时统计信息,并在事务提交或回滚后记录到共享的内存中.这些信息可以通过 "pg_stat_all_tables视图& ...
- 一文读懂HTTP/2及HTTP/3特性
摘要: 学习 HTTP/2 与 HTTP/3. 前言 HTTP/2 相比于 HTTP/1,可以说是大幅度提高了网页的性能,只需要升级到该协议就可以减少很多之前需要做的性能优化工作,当然兼容问题以及如何 ...
- 一文读懂AI简史:当年各国烧钱许下的愿,有些至今仍未实现
一文读懂AI简史:当年各国烧钱许下的愿,有些至今仍未实现 导读:近日,马云.马化腾.李彦宏等互联网大佬纷纷亮相2018世界人工智能大会,并登台演讲.关于人工智能的现状与未来,他们提出了各自的观点,也引 ...
- 从HTTP/0.9到HTTP/2:一文读懂HTTP协议的历史演变和设计思路
本文原作者阮一峰,作者博客:ruanyifeng.com. 1.引言 HTTP 协议是最重要的互联网基础协议之一,它从最初的仅为浏览网页的目的进化到现在,已经是短连接通信的事实工业标准,最新版本 HT ...
- 一文读懂 深度强化学习算法 A3C (Actor-Critic Algorithm)
一文读懂 深度强化学习算法 A3C (Actor-Critic Algorithm) 2017-12-25 16:29:19 对于 A3C 算法感觉自己总是一知半解,现将其梳理一下,记录在此,也 ...
- [转帖]MerkleDAG全面解析 一文读懂什么是默克尔有向无环图
MerkleDAG全面解析 一文读懂什么是默克尔有向无环图 2018-08-16 15:58区块链/技术 MerkleDAG作为IPFS的核心数据结构,它融合了Merkle Tree和DAG的优点,今 ...
- [转帖]从HTTP/0.9到HTTP/2:一文读懂HTTP协议的历史演变和设计思路
从HTTP/0.9到HTTP/2:一文读懂HTTP协议的历史演变和设计思路 http://www.52im.net/thread-1709-1-2.html 本文原作者阮一峰,作者博客:r ...
随机推荐
- Java线程:新特征-条件变量
条件变量是Java5线程中很重要的一个概念,顾名思义,条件变量就是表示条件的一种变量.但是必须说明,这里的条件是没有实际含义的,仅仅是个标记而已,并且条件的含义往往通过代码来赋予其含义. 这里的条 ...
- Windows下搭建Linux开发环境(vagrant)
[下载] vagrant软件:https://www.virtualbox.org/wiki/Downloads centos镜像: http://isoredirect.centos.org/cen ...
- goland之基础使用
安装go之后, 1.设置环境变量 GOROOT,GOPATH 2.goland配置 配置GOPATH GO Modules GOPROXY=https://goproxy.io,direct 设置自动 ...
- RocketMQ系列1:基础介绍
★消息队列16篇 1 认识RocketMQ RocketMQ是一款基于Java开发的分布式消息中间件,它以其高性能.高可靠性.高实时性以及分布式特性而广受好评. 它支持事务消息.顺序消息.批量消息.定 ...
- 交易系统:电商、O2O、线下门店购物流程详解
大家好,我是汤师爷~ 新零售业务涉及多个销售渠道,每个渠道都有其独特的业务特点,需要相应的营销方式.运营策略和供应链管理. 主要销售渠道包括:实体门店(包括直营连锁店.加盟门店).电商平台销售(如淘宝 ...
- LALR语法分析表
LALR语法分析表 1.LALR(向前看-LR)技术 2.在实践中常用,分析表比规范LR分析表小 LALR(1)项集族的内核的高效计算方法 1.构造G的LR(0)项集族的内核 2.确定自发生的符号 3 ...
- Redis原理—4.核心原理摘要
大纲 1.Redis服务器的Socket网络连接建立 2.Redis多路复用监听与文件事件模型 3.基于队列串行化的文件事件处理机制 4.完整的Redis Server网络通信流程 5.Redis串行 ...
- 腾讯技术岗位笔试&面试题(四)
说在前面 本篇文章是腾讯技术面试题目汇总第四篇. 后续将持续推出互联网大厂,如阿里,腾讯,百度,美团,头条等技术面试题目,以及答案和分析. 欢迎大家点赞关注转发. 原文链接:https://mp.we ...
- Centos7.8安装Gitlab
公司为了合规性考虑,需要自己搭建私有化版的github.那不用想,肯定要上GitLab了. 项目背景: 服务器:华为云ECS,需要上公网,并在安全组打开80端口访问. 用户:关闭公开注册,新建用户后, ...
- 中电金信:零售经营“新赛道” ——基于手机银行APP专区调研的客群精细化运营分析报告
随着银行业竞争的不断深入及新客户增量日渐"到顶",各家银行的客群竞争逐渐由"跑马圈地"进入"精耕细作"的新阶段,在客群精准化服务方面不断深 ...