super与this

目录

我们可能会对一个问题感到好奇:为什么在派生类中,我们需要在调用this 之前调用super 。我们通常将其视为一种规范,却很少深入探究这个规范的真正意义。许多人认为super 不过是ES6 之前继承方式的语法糖。但实际上,这种看法是不准确的。要真正理解super 的必要性,我们必须探究JavaScript中继承机制的内部工作原理

原型链与继承

在JavaScript 中,继承的实现本质上是通过原型链的查找机制来完成的。这个过程涉及将一个类(如Person )的实例作为另一个类(如Student )的原型。这样,Student 类实例就能够访问Person 类的属性和方法,从而实现继承

javascript 复制代码
class Person {
}
class Student extends Person {
}
const p1 = new Student()
const p2 = new Person()
console.log(p1)
console.log(p2)

我们观察一下p1和p2的原型链

我们先来观察一下p2 的原型链关系,因为p2 是直接通过new Person得到的,Person 是基类,所以不存在继承关系,p2.__proto__直接指向了Person.prototype,Person.prototype.__proto__直接指向了Object.prototype,Object.prototype.__proto__直接指向了null

继承中的原型链

再看看p1 的原型链,因为p1通过new Student得到,,所以p1.__proto__为Student.prototype,而Student继承了Person,所以Student.prototype.__proto__指向了Person.prototype

粗看似乎和Person 的原型链并没有什么不同,但仔细观察就会发现Student.__proto__指向了Person 自身,即指向了Person.prototype.constructor,这一点似乎与我们之前在ES5实现的继承并不相同

class

那么,为什么class 中的继承与ES5 中的继承不一致呢

我们知道,在class 中如果使用了extends 就需要在constructor 中调用super 方法,而且必须在派生类构造方法返回前且访问this前调用

在面向对象编程语言中,继承机制通常首先确保父类的构造函数被正确调用以初始化this对象,然后这个this对象会被传递给子类。这种做法被认为是更安全的

相比之下,在ES5 及之前的JavaScript 版本中,继承可以通过借用构造函数 或组合寄生继承 实现,这些方式允许开发者选择是先调用父类构造函数还是子类构造函数。这种灵活性使得JavaScript 在ES6 引入class 关键字之前,虽然具有对象构造的能力,但并不完全符合传统意义上的面向对象编程语言的规范

super与this

那么回到我们最开始的问题 ,为什么派生类在调用super 前不能访问this 呢

我们可以认为,在ES6 中,ECMA委员会 对类的继承机制进行了调整,从直接由子类发出this 给父类的情况变为了从父类发出this 并依次传递到子类,我们可以合理认为super 本身是有返回值的,而这个返回值就是this ,所以我们可以进一步得出子类的this 是由父类得到的,所以在访问this 前必须调用super

javascript 复制代码
let obj = null
class Person {
    constructor() {
        this.name = "person"
    }
    getName() {
        return this.name
    }
}
class Student extends Person {
    constructor() {
        obj = super()
        console.log(obj === this)
    }
}
const p1 = new Student()
console.log(p1 === obj)
相关推荐
RobinDevNotes2 小时前
从 Electron 到 GPUI,9 个跨平台桌面方案该怎么选
前端·javascript·rust·electron·openresty·前端开发工具
程序员大阳3 小时前
HTML+CSS+JS对话式实战(6)-学生端查看活动功能开发
javascript·css·html·模块·查看学生
噢,我明白了4 小时前
JAVA中的一些基础应用知识点
java·开发语言
时间的拾荒人5 小时前
Redis 入门详解:核心特性、重要文件与全局命令实战
开发语言·redis·面试
敲上瘾5 小时前
Qt Widgets入门:项目模板解析与Hello World
开发语言·数据库·c++·qt·ui·qt6.3
码途行者7 小时前
网站的SQL 注入:从攻击原理到防御措施
开发语言·sql·php
旖旎夜光7 小时前
【C++ 基础入门】C++ 多态(中):虚函数表、多态原理与动静绑定
开发语言·c++·笔记·学习
你看我名字7 小时前
产品参数昨天还对,今天已过期:数眼智能与大模型应用如何做资料版本校验
开发语言·架构
老秦包你会8 小时前
计算机网络第二课 ----Socket(套接字)编程预备
开发语言·计算机网络·php
旖旎夜光8 小时前
【C++ 基础入门】C++多态(下):单/多继承虚表、多态补充与 21 道高频题
开发语言·c++·笔记·学习