ECMAScript 6入门类继承笔记

news/2023/12/1 7:56:29

类继承

看类继承前,先回顾构造函数怎么实现对象的继承的

        function F() {
            this.a = 1;
        }
        function Son() {
            F.call(this);
        } 
        function inherit(S, F) {
            S.prototype = Object.create(F.prototype);
            S.prototype.constructor = S;
        }
        inherit(Son, F);
        let son = new Son();
        

它实现了哪几个功能:

  • 继承F的this属性也就是F实例对象的属性
  • Son.prototype.__proto__ === F.prototype 实现了上下辈分的继承
  • son.constructor让son认祖归宗

同样类继承也是如此

用来extends和super关键字,看一个简单的继承

        class A {
            constructor() {
                this.a = 1;
            }
        }
        class B extends A {
            constructor() {
                super();
                this.b = 2;
            }
            m() {

            }
        }
        let b = new B();

同样实现了那三点基本功能

B {a: 1, b: 2}
b.__proto__  == B.prototype
b.__proto__.__proto__ === A.prototype
b.constructor === B

我认为:关键字extends实现了原型的继承,以及constructor的修正;关键字super实现了父类this的继承,这里的super相当于A.prototype.constructor.call(this)

注意点

  • 写了constructor,就必须在里面写super,不然new子类实例对象会报错;要么都不写;其次子类的中constructor中的this属性必须写在super后面

    1.ES5 的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this))。ES6 的继承机制完全不同,实质是先将父类实例对象的属性和方法,加到this上面(所以必须先调用super方法),然后再用子类的构造函数修改this
    2.因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实 例属性和方法。如果不调用super方法,子类就得不到this对象。
            class B extends A {
                constructor() {    //要么都不写,new时默认会自动生成
                    super();
                    this.b = 2;    //写在super后面
                } 
                m() {
    
                }
            }

super的各种指向问题

  • super作为函数,只能放在子类的constructor中,指向A.prototype.constructor.call(this)
  • super作为对象,在子类普通方法中调用,super就是父类的原型也就是A.prototype;所以只能调用原型链上的方法,不能动用父类实例的方法和属性constructor{}中的不能调用

            class A {
                constructor() {
    
                    this.a = 1;
                }
                n() {
    
                    return this;
                }
            }
            class B extends A {
                constructor() {
                    
                    super();
                    this.b = 2;
                    
                }
                m() {
                    return super.n();
                }
            }
            let b = new B();
            b === b.m();

    并且规定

    在子类普通方法中通过super调用父类的方法时,方法内部的this指向当前的子类实例。

    所以上面return 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
        console.log(super.valueOf() instanceof B);   //true
      }
    }
    
    let b = new B();
  • super作为对象,在静态方法中指向的是父类能调用父类的静态方法,如果方法内部有this则指向当前的子类
    只有类才能调用类的静态方法

            class A {
                constructor() {
    
                    this.a = 1;
                }
                static n() {
    
                    return this;
                }
            }
            class B extends A {
                constructor() {
                    
                    super();
                    this.b = 2;
                    
                }
                static m() {
                    return super.n();
                }
            }
            console.log(A.n() === A)   // true
            console.log(B === B.m());  //true
    由于对象总是继承其他对象的,所以可以在任意一个对象中,使用super关键字。
    var obj = {
      toString() {
        return "MyObject: " + super.toString();
      }
    };
    Object.getPrototypeOf(obj).toString = function () {
        return "这里super等于obj.__proto__";
    }
    console.log(obj.toString());        //MyObject: 这里super等于obj.__proto__

类的prototype与__proto__

(1)子类的__proto__属性,表示构造函数的继承,总是指向父类。
(2)子类prototype属性的__proto__属性,表示方法的继承,总是指向父类的prototype属性。
类的继承模式
class A {
}

class B {
}

// B 的实例继承 A 的实例
Object.setPrototypeOf(B.prototype, A.prototype);

// B 继承 A 的静态属性
Object.setPrototypeOf(B, A);

const b = new B();

也是因为这种实现所以类能调用自己的静态方法

es6实现了原始构造函数的继承

之前Array.apply(this)this并不会塑造Array里面的内部结构,所以我们当我们用类数组对象引用数组方法时用null代替了
而es6用类实现它的继承,
代码摘自es6入门

class MyArray extends Array {
  constructor(...args) {
    super(...args);
  }
}

var arr = new MyArray();
arr[0] = 12;
arr.length // 1

arr.length = 0;
arr[0] // undefined

需要注意的是

ES6 改变了Object构造函数的行为,一旦发现Object方法不是通过new Object()这种形式调用,ES6 规定Object构造函数会忽略参数。
class NewObj extends Object{
  constructor(){
    super(...arguments);
  }
}
var o = new NewObj({attr: true});
o.attr === true  // false
传入参数会无效的

http://www.niftyadmin.cn/n/1693676.html

相关文章

从“走出淘系”到“Ad Tech”,阿里妈妈迎来品牌焕新

新标识 近日,阿里巴巴集团CMO、阿里妈妈总裁董本洪在内部发送了阿里妈妈全员邮件,宣布阿里妈妈启用新logo,通过品牌焕新提升“Ad Tech”品牌战略的重要性。 这是阿里妈妈在10月17日召开重要产品发布会、透露信息流营销新产品后的又一重要动作…

Office 365绝技系列:3分钟完成PPT设计排版

几个月前跟大家分享了如何一键翻译高质量的翻译PPT,有了这样的神器相信大家拿到外语PPT会淡定不少。但就翻译功能来讲,可能有小伙伴急了,我只是个普通信息工作者,没有外语PPT、不需要翻译!似乎翻译功能确实不是每个使用…

layer数据表格换行

在使用layer数据表格的时候,默认是不可以换行的。这样显示 改动后 数据格式为 aa<br>bb就会显示为换行 比如我们的字符串是 a<br>b 这样的字符串浏览器会把它解析换行的&#xff0c;但是layer的数据表格的单元格高度就是那么高&#xff0c;不变&#xff0c;底…

远程连接工具SSH Secure的使用

2019独角兽企业重金招聘Python工程师标准>>> 操作Linux操作系统&#xff0c;可以直接在虚拟机上&#xff0c;但是实际生产环境&#xff0c;Linux在其他的地方&#xff0c;我们需要远程连接。有很多种连接工具&#xff0c;这里介绍SSH Secure工具。 安装包如下&#…

Java图书管理系统练习程序(三)

2019独角兽企业重金招聘Python工程师标准>>> Java图书管理系统练习程序&#xff08;三&#xff09; 本部分内容主要实现将用户信息写入文件中&#xff0c;并在程序执行时&#xff0c;将文件中的用户信息读入到内存中&#xff0c;实现用户信息的存储。 将Java对象序列…

java.lang.AbstractMethodError 第三方jar依赖混淆

1.场景&#xff1a;libA,libB; 其中libB又依赖libA,在对libB进行混淆后调用时libA报java.lang.AbstractMethodError。解决方法&#xff1a; 在libB的混淆中添加下面语句: 1 -libraryjars ./libA.jar 将libA.jar添加为当前混淆的依赖jar。 转载于:https://www.cnblogs.com/uini…

【dfs+dp】砝码称重

P1441 砝码称重 思路&#xff1a;dfs枚举去掉哪些砝码&#xff0c; 01背包求方案数&#xff0c; 各种情况取max记为ans输出√ 边界情况处理不好交了三遍QAQ dp[j] dp[j] dp[j - a[i]] 选上这个砝码的情况 不选的情况 1 #include<cstdio>2 #include<cstring>3 #in…

自定义 Laravel 5.6 MethodNotAllowedHttpException /NotFoundHttpException 错误信息

2019独角兽企业重金招聘Python工程师标准>>> use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; public function render($request, Exception $exception) {// 接口…

python 3.7极速入门教程1安装:Linux(Ubuntu 18.04)及Windows上安装Anaconda

2019独角兽企业重金招聘Python工程师标准>>> 安装 Linux安装 Anaconda是最受欢迎的python数据科学和机器学习平台&#xff0c;用于大规模数据处理&#xff0c;预测分析和科学计算。Anaconda发行版附带了1,000多个数据包&#xff0c;conda命令行工具和Anaconda Navig…

从零开始搭建物联网平台(1):开篇

前言&#xff1a; 读大学的时候学的是物联网工程&#xff0c;大概是在大二的时候开始接触单片机&#xff0c;那时候特喜欢捣鼓那些东西&#xff0c;就觉得特别酷有极客范。还记得第一次做物联网相关的是一个远程控制的开关&#xff0c;第一次调通的时候真的很兴奋&#xff0c;啥…

react 修改state某一属性值

1.state // 筛选框相关数据searchSelect: { term: { value: 学期, key: , options: [] }, type_of_personnel: { value: 教师类型, key: , options: [] }, business_type: { value: 业务类型, key: , options: [] },cycle_year: { value: 年, key: , options: [] },cycle_month…

js高级正则式

贪婪和非贪婪 默认是贪婪的&#xff0c;如/a/则会尽可能多的匹配a&#xff0c;如果想要尽可能少的匹配&#xff0c;则需要加?,即/a?/ 子表达式与反向引用 $1&#xff0c;$2匹配子表达式&#xff0c;$&全匹配的字符串\1反向引用&#xff0c;引用在正则表达式中&#xff0c…

架构设计-支付宝、京东、美团、去哪儿的支付系统架构整体设计详解!!!

架构设计-支付宝、京东、美团、去哪儿的支付系统架构整体设计详解&#xff01;&#xff01;&#xff01; 支付产品模块是按照支付场景来为业务方提供支付服务。这个模块一般位于支付网关之后&#xff0c;支付渠道之前。 它根据支付能力将不同的支付渠道封装成统一的接口&#x…

如何将数据热导出到文件

随着时间推移&#xff0c;数据库中数据量会越来越大&#xff0c;如果把查询分析都挂到数据库上&#xff0c;有可能会影响到生产系统的正常运行。所以&#xff0c;一般都会将生产数据库中不再变动的数据定期移出到另一个分析数据库中&#xff0c;由分析数据库来承担查询分析的压…

Win10-EOS-Docker单节点环境快速搭建

环境 操作系统&#xff1a;Windows 10专业版 Docker Server: 18.03.1-ce Docker Client: 18.03.1-ce 命令行工具Cmder: 171025 基础知识 操作系统&#xff1a;文件、目录... Docker&#xff1a;容器、镜像、仓库、数据、网络、编排 EOS&#xff1a;nodeos、cleos、keosd的概念…

【ES6】var、let、const三者的区别

首先&#xff0c;一个常见的问题是&#xff0c;ECMAScript 和 JavaScript 到底是什么关系&#xff1f; ECMAScript是一个国际通过的标准化脚本语言。JavaScript由ECMAScript和DOM、BOM三者组成。可以简单理解为&#xff1a;ECMAScript是JavaScript的语言规范&#xff0c;JavaSc…
最新文章