理解 es6 class 中 constructor 方法 和 super 的作用

2023-11-17

首先,ES6 的 class 属于一种“语法糖”,所以只是写法更加优雅,更加像面对对象的编程,其思想和 ES5 是一致的。

function Point(x, y) {
  this.x = x;
  this.y = y;
}

Point.prototype.toString = function() {
  return '(' + this.x + ',' + this.y + ')';
}
复制代码

等同于

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ',' + this.y + ')';
  }
}
复制代码

其中 constructor 方法是类的构造函数,是一个默认方法,通过 new 命令创建对象实例时,自动调用该方法。一个类必须有 constructor 方法,如果没有显式定义,一个默认的 consructor 方法会被默认添加。所以即使你没有添加构造函数,也是会有一个默认的构造函数的。一般 constructor 方法返回实例对象 this ,但是也可以指定 constructor 方法返回一个全新的对象,让返回的实例对象不是该类的实例。

下面好好分析一下 super 关键字的作用:

super 这个关键字,既可以当做函数使用,也可以当做对象使用。这两种情况下,它的用法完全不用。

1. 当做函数使用
class A {}
class B extends A {
  constructor() {
    super();  // ES6 要求,子类的构造函数必须执行一次 super 函数,否则会报错。
  }
}
复制代码

注:在 constructor 中必须调用 super 方法,因为子类没有自己的 this 对象,而是继承父类的 this 对象,然后对其进行加工,而 super 就代表了父类的构造函数。super 虽然代表了父类 A 的构造函数,但是返回的是子类 B 的实例,即 super 内部的 this 指的是 B,因此 super() 在这里相当于 ```A.prototype.constructor.call(this, props)``。

class A {
  constructor() {
    console.log(new.target.name); // new.target 指向当前正在执行的函数
  }
}

class B extends A {
  constructor {
    super();
  }
}

new A(); // A
new B(); // B
复制代码

可以看到,在 super() 执行时,它指向的是 子类 B 的构造函数,而不是父类 A 的构造函数。也就是说,super() 内部的 this 指向的是 B。

2. 当做对象使用

在普通方法中,指向父类的原型对象;在静态方法中,指向父类。

class A {
  c() {
    return 2;
  }
}

class B extends A {
  constructor() {
    super();
    console.log(super.c()); // 2
  }
}

let b = new B();
复制代码

上面代码中,子类 B 当中的 super.c(),就是将 super 当作一个对象使用。这时,super 在普通方法之中,指向 A.prototype,所以 super.c() 就相当于 A.prototype.c()

通过 super 调用父类的方法时,super 会绑定子类的 this

class A {
  constructor {
    this.x = 1;
  }
  s() {
    console.log(this.x);
  }
}

class B extends A {
  constructor {
    super();
    this.x = 2;
  }
  m() {
    super.s();
  }
}

let b = new B();
b.m(); // 2
复制代码

上面代码中,super.s() 虽然调用的是 A.prototytpe.s(),但是 A.prototytpe.s()会绑定子类 B 的 this,导致输出的是 2,而不是 1。也就是说,实际上执行的是 super.s.call(this)

由于绑定子类的 this,所以如果通过 super 对某个属性赋值,这时 super 就是 this,赋值的属性会变成子类实例的属性。

class A {
  constructor {
    this.x = 1;
  }
}

class B extends A {
  constructor {
    super();
    this.x = 2;
    super.x = 3;
    console.log(super.x); // undefined
    console.log(this.x); // 3
  }
}

let b = new B();
复制代码

上面代码中,super.x 赋值为 3,这时等同于对 this.x 赋值为 3。而当读取 super.x 的时候,调用的是 A.prototype.x,但并没有 x 方法,所以返回 undefined。

注意,使用 super 的时候,必须显式指定是作为函数,还是作为对象使用,否则会报错。

class A {}
class B extends A {
  constructor() {
    super();
    console.log(super); // 报错
  }
}
复制代码

上面代码中,console.log(super); 的当中的 super,无法看出是作为函数使用,还是作为对象使用,所以 JavaScript 引擎解析代码的时候就会报错。这是,如果能清晰的表明 super 的数据类型,就不会报错。

最后,由于对象总是继承其他对象的,所以可以在任意一个对象中,使用 super 关键字。

结语:
ES6 的 class 毕竟是一个“语法糖”,所以只要理解了 JavaScript 中对象的概念和面向对象的思想,class 就不难理解啦。



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

理解 es6 class 中 constructor 方法 和 super 的作用 的相关文章

  • 更改样式表 JavaScript

    我得到了这个 HTML 代码
  • 通过 HTTPS 加载页面但请求不安全的 XMLHttpRequest 端点

    我有一个页面 上面有一些 D3 javascript 该页面位于 HTTPS 网站内 但证书是自签名的 当我加载页面时 我的 D3 可视化效果不显示 并且出现错误 混合内容 页面位于 https integration jsite com
  • 为什么 lodash 将我的数组转换为对象?

    我是 lodash 的新手 创建了一个函数 该函数从值为 null 或空白的对象中删除键 但是当我传递包含某些部分作为数组的对象时 它会删除数组并将其转换为对象 下面是我尝试过的代码 mixin removeFalsies this rem
  • RxJS - 我需要取消订阅吗

    如果我有这样的事情 class MyComponent constructor this interval Observbale interval 1000 const c new MyComponent const subscriptio
  • 节点异步循环 - 如何使该代码按顺序运行?

    我知道有几个关于此的帖子 但根据我发现的那些帖子 这应该可以正常工作 我想在循环中发出 http 请求 并且不希望循环迭代 直到触发请求回调 我正在使用异步库 如下所示 const async require async const req
  • Webpack将js/css文件内容直接注入到index.html

    我有这样的代码
  • 应该使用encodeURI吗?

    javascript 的encodeURI 函数有任何有效用途吗 据我所知 当您尝试发出 HTTP 请求时 您应该 完整的 URI 您想要放入 URI 中的某些片段 可以是 unicode 字符串或 UTF 8 字节序列 在第一种情况下 显
  • React 无法识别 DOM 元素上的 `isActive` 属性 - styled-components

    我有以下内容svg我传递道具的组件 import React from react export default props gt
  • 无法使用 Jade 模板包含相对路径文件

    当我尝试将文件包含在同一文件夹中时 收到以下错误 the filename option is required to use include with relative paths 有两个文件 索引 jade 项目列表 jade cont
  • 按 Enter 键提交消息?

    我正在开发一个基于本教程使用 Meteor 构建的聊天应用程序 http code tutsplus com tutorials real time messaging for meteor with meteor streams net
  • 如何对像 Excel Pivot 这样两个键必须匹配的数组求和?

    我尝试对 Datum 和 Material 必须匹配的所有 Menge 和 Fehler 值求和 结果应类似于 Excel 数据透视表 到目前为止 这是我的代码 但我不知道如何添加也必须匹配的第二个键 Material 我希望你能理解我试图
  • 如何使用 JavaScript 压缩文件?

    有没有办法使用 JavaScript 来压缩文件 例如 在雅虎邮件中 当您选择下载电子邮件中的所有附件时 它会被压缩并下载到单个 zip 文件中 JavaScript 能够做到这一点吗 如果是这样 请提供一个编码示例 我发现这个图书馆叫js
  • FileReader 在 Ionic 2 中未触发 onloadend

    我正在尝试使用 cordova file plugin 读取本地文件 目前我可以读取本地目录的内容并选择单个文件 但我在获取文件内容时遇到问题 这是我的函数 从列表中选择文件后单击按钮即可调用该函数 import window resolv
  • 如何使用 ReactJS 使表中的列可以以两种方式排序

    我正在 ReactJS 中构建一个简单的应用程序 它通过调用某个 API 来使用 JSON 数组 然后我将数组的结果填充到表中 我现在想让表的列可排序 我理想的情况是同时进行升序和降序排序 一旦我单击标题 当它按升序排序时 它应该按降序排序
  • JavaScript 中的安全数据

    我必须为 Web 测试创建生成器 使用 HTML 和 JavaScript 测试必须离线和在线进行 正确答案和分数评估必须是生成的测试的一部分 最终用户的分数仅发送到服务器 无法在服务器上进行评估 并且服务器对问题一无所知 它只保存最终分数
  • 数据表 - 从 AJAX 源过滤数据

    我有一个数据表 正在从 api 获取数据 现在我的状态是活动的 非活动的 如果标志是活动的 那么我需要在数据表中显示 否则我不应该显示过期的 这是我的fiddle https jsfiddle net lakshmipriya001 qLp
  • 鼠标输入时反应显示按钮

    我有一个反应组件 它包含如下方法 mouseEnter console log this is mouse enter render var album list const albums this props if albums user
  • 阻止 PM2 上不同时运行的请求

    在我的 Express 应用程序中 我在应用程序中定义了 2 个端点 一种用于 is sever up 检查 另一种用于模拟阻塞操作 app use status req res gt res sendStatus 200 app use
  • 从 node.js 创建对 AWS ES 实例的有效签名请求

    我试图找到一个示例 说明如何连接到 Node js 中的 AWS ES 实例 然后通过一个简单的请求访问 ES 集群 我正在尝试使用elasticsearch节点包 https www npmjs com package elasticse
  • 了解客户端文件的对象 URL 以及如何释放内存

    我在用createObjectURL获取本地图像文件的引用 URL 当我完成文件 图像后 我打电话revokeObjectURL释放该内存 一切对我来说都很好 但我只是想确保我释放了我能释放的所有内存 我检查后出现了我的担忧chrome b

随机推荐

  • 如何在Ubuntu20下安装Android studio

    安装jdk 安装jdk 安装Android studio 的前提是要先配置好 jdk 环境 我这里下载的是 jdk 8u251 linux x64 tar gz 解压到指定文件夹下 tar zxvf jdk 8u251 linux x64
  • epoch、batch、batch size和mini-batch的区别

    epoch batch batch size和mini batch的区别 epoch batch batch size和mini batch都是深度学习中常见的名词 初学时经常混淆 在此整理 epoch 当一个完整的数据集经过神经网络一次
  • QSettings使用中出现的问题及正确示例

    为什么80 的码农都做不了架构师 gt gt gt 背景 使用QSettings读写配置文件 示例及需要注意的问题 写配置文件 QSettings settings Option ini QSettings IniFormat settin
  • [900]mysql字符串数字互转

    文章目录 字符串转数字 CAST 函数转化为整数 CAST 函数转化为浮点数 CONVERT方法转化为整数 CONVERT方法转化为浮点数 数字转为字符串 CONVERT方法转化为字符串 字符串转数字 最简单的方式就是直接在字符串后面 0
  • #systemverilog# 之 event region 和 timeslot 仿真调度(九)assign 赋值 和 always 组合赋值的调度区别

    有时候 我们会发现一个问题 举个最简单的例子 比如将两个信号进行简单的异或运算 该逻辑运算 我们可以使用 assign 数据流建模完成 也可以使用always 组合逻辑过程赋值语句实现 那仿真工具在对它进行调度的时候 有什么区别吗 不慌 今
  • Ubuntu安装可视化界面ElasticSearch-head插件

    1 下载地址 GitHub mobz elasticsearch head A web front end for an elastic search cluster 上传并解压 root zq virtual machine home e
  • 一次url请求的过程

    1 HTTP协议 超文本传输协议 Hyper Text Transfer Protocol HTTP 一个简单的请求 响应协议 指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应 2 域名解析 DNS Domain Name Sy
  • 如何开启bios虚拟化

    要开启 BIOS 虚拟化 首先需要进入 BIOS 设置 通常可以在电脑启动时按下 F2 或 Del 键进入 具体操作可能因电脑品牌和型号而异 在 BIOS 设置中 需要找到 虚拟化支持 或 硬件虚拟化 选项 并将其设置为 开启 有些电脑可能
  • 货币的教训——汇率与货币系列评论

    这本书中介绍了中国的人民币的具体的流转形式 就是不知到底准确否 2013 9 29
  • numpy广播机制

    NumPy的广播机制 文章目录 NumPy的广播机制 Broadcast 最简单的广播机制 稍微复杂的广播机制 广播机制到底做了什么 一个典型的错误案例 一个正确的经典示例 一种更便捷的计算方式 Broadcast 广播是numpy对不同形
  • 【计算机视觉

    文章目录 一 分割 语义相关 12篇 1 1 UniSeg A Unified Multi Modal LiDAR Segmentation Network and the OpenPCSeg Codebase 1 2 Learning S
  • IDEA导入eclipse项目

    第一步 File gt new gt Project from Existing Sources 导入已存在的项目 并选择要导入的文件或目录 第二步 选择eclipse选项 第三步 配置jdk 导入完成了 项目目录如图示 gt 开始配置mo
  • PCB 过孔简介

    做过 PCB 设计的最先了解的应该就是过孔了 因为有过孔的存在我们才能做出多层板 过孔应该是 PCB 中最简单的部分了 也是最容易被我们忽略的地方 常见的过孔分为两大类 1 用作各层之间的电气连接 2 用作器件的固定或定位 一 过孔的介绍
  • 如何判断三点共线

    如何判断三点共线 在二维坐标系中 给出三点A x1 y1 B x2 y2 C x3 y3 的坐标 判断三点共线的条件是 实质是判断有三个点组成的三角形面积为0 神爱世人 甚至将他的独生子 耶稣 赐给他们 叫一切信他的 不至灭亡 反得永生 圣
  • 智能制造面临的主要问题

    随着工业4 0的发展 工业互联网 智能制造 智能工厂等概念正在兴起 但从本质上讲 制造业的目标是利用大数据 人工智能 互联网等先进技术改造制造业 使制造业成为定制体验 创新交付的竞争核心 在逐步实施工业4 0和中国制造2025的背景下 国内
  • R语言-引用函数对象作为参数

    问题描述 如何在在R的函数中通过字符串调用别的函数 以下面为例子 testFun lt function Fun x lt 1 100 Fun x 解法 这个问题没什么其实很笨 就是想记录一下 1 直接调用 testFun lt funct
  • 文本后缀“SCRIPT_EXP”无效;未找到文文本运算符或文本运算符模板“operator ““““SCRIPT_EXP”

    今天下载了一份源码 然后在编译的时候出现了这个问题 我查阅了相关资料 解决方法有两个 下面列举一下 1 字符文件编码 Visual Studio编译器 首先选中代码当前页 然后文件 gt 打开 高级保存选项 选中GB2312 确定 2 空格
  • HBase篇(1)-特性与应用场景

    结束了Zookeeper篇 接下来我们来说下Google三驾马车之一BigTable的开源实现 HBase 要讲的内容暂定如下 这是第一篇我们先不聊技术实现 只讨论特性和场景 hbase的特点 千万级高并发 PB级存储 非结构化存储 动态列
  • 树莓派升级ubuntu mate 16.04 到 18.04

    gt gt gt sudo do release upgrade Checking for a new Ubuntu release Get 1 Upgrade tool signature 819 B Get 2 Upgrade tool
  • 理解 es6 class 中 constructor 方法 和 super 的作用

    首先 ES6 的 class 属于一种 语法糖 所以只是写法更加优雅 更加像面对对象的编程 其思想和 ES5 是一致的 function Point x y this x x this y y Point prototype toStrin