class的继承(笔记)

子类通过extends关键字继承父类。

class Par{
    constructor(){
        this.num=21;
    }
}
class  Chil  extends Par{
    constructor(){
      //继承父类的构造函数constructor
        super() //这里必须写,否则下面实例会报错。
    }
}

var p=new Chil();
console.dir(p.num) //21

注意:子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类实例的构建,基于父类实例,只有super方法才能调用父类实例。

ES5 继承和ES6 继承对比
  • ES5 的继承机制:是先创造子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this))。
  • ES6 的继承机制:是先将父类实例对象的属性和方法,加到this上面(所以必须先调用super方法),然后再用子类的构造函数修改this

super关键字

1.可以当函数用。
super作为函数调用时,代表父类的构造函数。

class A {}

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

注意:

  • super虽然代表了父类A的构造函数,但是返回的是子类B的实例,即super内部的this指的是B的实例,因此super()在这里相当于A.prototype.constructor.call(this)
  • super只能用在子类的constructor中。

2.可以作为对象使用。
super 作为对象使用时, 在普通的方法中,指向的是父类的原型对象。在静态方法中,指向的是父类。

class A {
  constructor() {
    // 这里是实例上的属性
    this.p = 1;
  }
  // 普通方法,放在A原型上的。
  say(){
    console.log("普通方法")
  }
  // 静态方法,能被子类继承,但是不能被实例化对象继承。
  static greeting(){
    console.log("静态方法")
  }
}
// 静态属性
A.age=22;

class B extends A {
  constructor(){
    super();
  }
  bsay(){
    // p是实例的属性,通过this访问
      console.log(this.p) //1
    // 在普通方法中,super指向的是父类原型对象,即prototype,
    // 所以能访问父类原型上的方法。
    super.say() // "普通方法";
  }
  static bgreeting(){
    // 在静态方法中,super指向的是父类,能访问父类的静态属性和静态方法。
    super.greeting(); //"静态方法"
    console.log(super.age); //22
  }
}

let xiao = new B();
xiao.bsay();
B.bgreeting(); 

要点总结:

  • 静态方法,能被子类继承,不能被实例对象继承。
  • 因为普通方法中,super指向的是父类原型对象。所以子类中,通过super只能访问到父类原型上的方法。
  • 在静态方法中,super指向的是父类,只能访问父类的静态属性和静态方法。
  • 普通方法中,this指向的是当前类的实例对象。
  • 静态方法中,this指向的是当前类。

类的 prototype 属性和proto属性

类同时有prototype属性和__proto__属性,因此同时存在两条继承链。
例子:

class Par{
    constructor(){
        // ....
    }
    say(){
        console.log("我今年"+this.age+"岁了!")
    }
    static greeting(){
        console.log("hello")
    }
}
Par.num=101;
class  Chil  extends Par{
    constructor(){
        super()
    }
}
console.dir(Chil)
  • 子类的__proto__属性 ,指向父类。
    Chil.__proto__ === Par
    image.png
  • 子类prototype属性的__proto__属性,指向父类的prototype属性。
    Chil.prototype.__proto__ === Par.prototype

    image.png

  • 子类实例的__proto__属性的__proto__属性,指向父类实例的__proto__属性。也就是说,子类的原型的原型,是父类的原型。
    Chil.__proto__.__proto__ === Par.__proto__

原生构造函数继承

  • Boolean()

  • Number()

  • String()

  • Array()

  • Date()

  • Function()

  • RegExp()

  • Error()

  • Object()

  • ES5 是先新建子类的实例对象this,再将父类的属性添加到子类上,由于父类的内部属性无法获取,导致无法继承原生的构造函数。

  • ES6 允许继承原生构造函数定义子类,因为 ES6 是先新建父类的实例对象this,然后再用子类的构造函数修饰this,使得父类的所有行为都可以继承。

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

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

arr.length = 0;
arr[0] // undefined
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 简介 Class 可以通过extends关键字实现继承,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多。...
    emmet7life阅读 2,870评论 0 0
  • 简介 Class可以通过extends关键字实现继承。 上面代码定义了一个ColorPoint类,该类通过exte...
    oWSQo阅读 3,966评论 0 1
  • class的基本用法 概述 JavaScript语言的传统方法是通过构造函数,定义并生成新对象。下面是一个例子: ...
    呼呼哥阅读 9,569评论 3 11
  • 基本语法 简介 JavaScript语言中,生成实例对象的传统方法是通过构造函数. ES6提供更接近传统语言的写法...
    JarvanZ阅读 4,375评论 0 0
  • 继承6种套餐 参照红皮书,JS继承一共6种 1.原型链继承 核心思想:子类的原型指向父类的一个实例 Son.pro...
    灯不梨喵阅读 8,384评论 1 2

友情链接更多精彩内容