一直以来有这么个疑问? 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.
在这个例子中:
  1. MyClass 是一个类,其中包含三个方法:greet、sayGoodbye 和 afterGoodbye。
  2. myInstance 是 MyClass 的一个实例,初始化时 name 属性被设置为 'Alice'。
  3. greet 方法正常调用时会输出 Hello, my name is Alice,因为 this 指向 myInstance。
  4. 当我们将 greet 方法提取到类之外并直接调用时,this 不再指向 myInstance,而是指向全局对象(在非严格模式下)或 undefined(在严格模式下),因此输出 Hello, my name is undefined。
  5. 使用 bind 方法手动绑定 this 到 myInstance 后,再次调用 greet 方法,this 指向 myInstance,输出 Hello, my name is Alice。
  6. sayGoodbye 方法在类内部调用 afterGoodbye 方法时,this 正常指向 myInstance,因此输出 Goodbye, Alice! After goodbye, Alice is still here.。
  7. 当我们将 sayGoodbye 方法提取到类之外并直接调用时,this 不再指向 myInstance,导致 this.name 输出 undefined,并且 this.afterGoodbye 不是一个函数,抛出 TypeError。
  8. 使用 bind 方法手动绑定 this 到 myInstance 后,再次调用 sayGoodbye 方法,this 指向 myInstance,输出 Goodbye, Alice! After goodbye, Alice is still here.。

通过这个例子,你可以看到手动绑定 this 的重要性,特别是在将方法提取到类之外调用时。

一文读懂 es6 中class方法中的this绑定的更多相关文章

  1. 一文读懂ES6(附PY3对比)

      Ⅰ.ES6~POP¶ 代码示例:https://github.com/lotapp/BaseCode/tree/master/javascript/1.ES6 在线演示:https://githu ...

  2. 一文读懂高性能网络编程中的I/O模型

    1.前言 随着互联网的发展,面对海量用户高并发业务,传统的阻塞式的服务端架构模式已经无能为力.本文(和下篇<高性能网络编程(六):一文读懂高性能网络编程中的线程模型>)旨在为大家提供有用的 ...

  3. 一文读懂神经网络训练中的Batch Size,Epoch,Iteration

    一文读懂神经网络训练中的Batch Size,Epoch,Iteration 作为在各种神经网络训练时都无法避免的几个名词,本文将全面解析他们的含义和关系. 1. Batch Size 释义:批大小, ...

  4. 一文读懂数仓中的pg_stat

    摘要:GaussDB(DWS)在SQL执行过程中,会记录表增删改查相关的运行时统计信息,并在事务提交或回滚后记录到共享的内存中.这些信息可以通过 "pg_stat_all_tables视图& ...

  5. 一文读懂HTTP/2及HTTP/3特性

    摘要: 学习 HTTP/2 与 HTTP/3. 前言 HTTP/2 相比于 HTTP/1,可以说是大幅度提高了网页的性能,只需要升级到该协议就可以减少很多之前需要做的性能优化工作,当然兼容问题以及如何 ...

  6. 一文读懂AI简史:当年各国烧钱许下的愿,有些至今仍未实现

    一文读懂AI简史:当年各国烧钱许下的愿,有些至今仍未实现 导读:近日,马云.马化腾.李彦宏等互联网大佬纷纷亮相2018世界人工智能大会,并登台演讲.关于人工智能的现状与未来,他们提出了各自的观点,也引 ...

  7. 从HTTP/0.9到HTTP/2:一文读懂HTTP协议的历史演变和设计思路

    本文原作者阮一峰,作者博客:ruanyifeng.com. 1.引言 HTTP 协议是最重要的互联网基础协议之一,它从最初的仅为浏览网页的目的进化到现在,已经是短连接通信的事实工业标准,最新版本 HT ...

  8. 一文读懂 深度强化学习算法 A3C (Actor-Critic Algorithm)

    一文读懂 深度强化学习算法 A3C (Actor-Critic Algorithm) 2017-12-25  16:29:19   对于 A3C 算法感觉自己总是一知半解,现将其梳理一下,记录在此,也 ...

  9. [转帖]MerkleDAG全面解析 一文读懂什么是默克尔有向无环图

    MerkleDAG全面解析 一文读懂什么是默克尔有向无环图 2018-08-16 15:58区块链/技术 MerkleDAG作为IPFS的核心数据结构,它融合了Merkle Tree和DAG的优点,今 ...

  10. [转帖]从HTTP/0.9到HTTP/2:一文读懂HTTP协议的历史演变和设计思路

    从HTTP/0.9到HTTP/2:一文读懂HTTP协议的历史演变和设计思路   http://www.52im.net/thread-1709-1-2.html     本文原作者阮一峰,作者博客:r ...

随机推荐

  1. cmu15545-数据访问方式:B+树(B+Tree)

    目录 基本概念 基于磁盘的B+树 查询与索引 设计选择 结点大小(Node Size) 合并阈值(Merge Thredshold) 变长键(Variable-length Keys) 结点内部搜索( ...

  2. pycharm生成的allure测试报告如何查看本地的index.html文件?

    pycharm生成的allure测试报告应该是通过服务启动查看,但是如果把这个文件保存到本地查看,直接打开页面无内容 可以使用allure-combine工具实现本地正常打开 `from allure ...

  3. [python] Python异步编程库asyncio使用指北

    Python的asyncio模块提供了基于协程(coroutines)的异步编程(asynchronous programming)模型.作为一种高效的编程范式,异步编程允许多个轻量级任务并发执行,且 ...

  4. 利用sqlmapapi和google-hacking联动自动化sql注入探测

    利用inurl语法搜索+sqlmap梭哈挖到过一点sql注入,这不失为一种好方法. 但是现在的sql注入漏洞的网站是比较少的了,所以这样一个个手工测,不仅效率低,还不一定有什么收获.不妨写一个goog ...

  5. Java的内存管理1:“并不只有C++程序员关心内存回收”——Java的内存管理2:"不中用的finalize( )方法"

    通常Java的缓存管理会由垃圾回收器(Java Garbage Collection)定时处理,无须程序员操心.但Java Garbage Collection仅有权回收那些非"强引用&qu ...

  6. AbstractQueuedSynchronizer源码解析之ReentrantLock(二)

    上篇文章分析了ReentrantLock的lock,tryLock,unlock方法,继续分析剩下的方法,首先开始lockInterruptibly,先看其API说明:lockInterruptibl ...

  7. HAR文件

    简介 HAR(HTTP Archive format),是一种或 JSON 格式的存档格式文件,通用扩展名为 .har.Web 浏览器可以使用该格式导出有关其加载的网页的详细性能数据. 使用场景 在开 ...

  8. API之接口服务

    聚合数据: https://www.juhe.cn/ 百度api市场: https://apis.baidu.com/

  9. MySQL底层概述—1.InnoDB内存结构

    大纲 1.InnoDB引擎架构 2.Buffer Pool 3.Page管理机制之Page页分类 4.Page管理机制之Page页管理 5.Change Buffer 6.Log Buffer 1.I ...

  10. log4j2 变量注入漏洞(CVE-2021-44228)

    log4j2 JNDI注入漏洞(CVE-2021-44228) 概述 本文非常详细的从头到尾debug了CVE-2021-44228漏洞的利用过程,喜欢的师傅记得点个推荐~ Apache Log4j2 ...