• class的继承


    extends

    class Point {
    }
    
    class ColorPoint extends Point {
    }

    通过extends关键字,实现子类对父类的继承

    但是在继承父类时,必须使用super关键字,调用父类的构造方法,首先生成一个父类的this对象,得到与父类相同的属性或方法,再对其进行加工,添加自己的属性和方法,才能得到自己的this对象。

    class Point {
                constructor(x, y) {
                    this.x = x;
                    this.y = y;
                }
            }
            class ColorPoint extends Point {
                constructor(x, y, color){
                    super(x, y);
                    this.color = color;
                }
            }

    在子类中,必须首先使用super,才能使用this关键字,因为this需要基于super先生成再改造。如果以上代码将this.color = color放到super之前,会报错。

    通过子类生成的实例,同时是父类和子类的实例

    子类会继承父类的静态方法。

    Object.getPropertyOf()

    可以用来获取子类的父类,从而判断一个类是否继承了另一个类

    Object.getPropertyOf(ColorPoint) === Point // true

     类的prototype和__proto__

    Class作为构造函数的语法糖,同时具有prototype和__proto__属性,存在两条继承链

    class father{
    }
    class son extends father{
    }
    son.__proto__ === father //true
    son.prototype.__proto__ === father.prototype // true

    这样的结果是因为,类的继承是如下方式实现的

    class A{}
    class B extends A{}
    
    Object.setPropertyOf(B.prototype, A.prototype);
    Object.setPropertyOf(B, A);

    而setPropertyOf方法的实现如下:

    Object.setPropertyOf = funtion(obj, proto){
      obj.__proto__ = proto;
      return obj;    
    }

    因此,以上类的继承

    B.prototype.__proto__ = A.prototype
    B.__proto__ = A

    只要的内部有prototype属性的函数都能被继承,而所有的函数都有prototype属性,所以任何函数都能被继承

    当A类作为基类时,其就是一个普通的函数,因此直接继承Function.prototype。而这个基类创建的实例是一个空对象,A.prototype__proto__又指向了Object.prototype

    class A{}
    A.__proto__ === Function.prototype // true
    A.prototype.__proto__ === Object.prototype  //true

    实例的__proto__属性

    class P1{
    constructor(name){
    this.name = name
    }
    sayHi(){
    console.log('hi~p1')
    }
    }
    class P2 extends P1{

    }
    var p1 = new P1('ashen');
    var p2 = new P2();
    console.log(p2.__proto__.__proto__ === p1.__proto__) // true

    子类实例的原型的原型,指向父类实例的原型

    正因如此,通过在子类实例的原型的原型可以更改父类的方法。但不能更改父类的实例属性

    p2.__proto__.__proto__.sayHi = function () {
                console.log('hi~p2')
            }
            p2.__proto__.__proto__.name = 'xing'
            p1.sayHi() // hi~p2
         console.log(p1.name) // ashen

    构建原型构造函数的子类

    在ES5中,继承都是先创建子类的this,再将父类的属性添加到子类上。然而父类的内部属性无法获取,也就无法继承原生的构造函数

    而在ES6中,是先创建父类的this,然后用子类的属性和方法修饰this。所以继承了父类所有的内部属性。因此在ES6中可以构造原型构造函数的子类,如下实现数组构造函数的继承

    class myArray extends Array{
                constructor(...args){
                    super(...args);
                }
            }
    
            var arr = new myArray();
            arr[0] = 12;
            console.log(arr.length);
            arr.length = 0;
            console.log(arr[0]);

    既然可以继承数据类型的构造函数,那么就可以在此基础上定义自己的数据结构

    但是在继承Object构造函数时有一个注意点

    class myObj extends Object{
                constructor(){
                    super(...arguments)
                }
            }
            var o = new myObj({attr: true});
            console.log(o.attr) // undefined

    无法通过super向父类构造函数传参。这是因为ES6中改变了Object构造函数的设置,当不是通过new Object()创建对象时,ES6就规定Object()构造函数忽略参数

  • 相关阅读:
    2020软件工程作业04
    2020软件工程作业03
    2020软件工程作业02
    2020软件工程作业01
    Linux操作系统分析-课程学习总结报告
    结合中断上下文切换和进程上下文切换分析Linux内核的一般执行过程
    深入理解系统调用
    基于mykernel 2.0编写一个操作系统内核
    交互式多媒体图书平台的设计与实现
    码农放入自我修养之必备技能学习笔记
  • 原文地址:https://www.cnblogs.com/ashen1999/p/12720964.html
Copyright © 2020-2023  润新知