• ES6之class的基础用法和class的继承


    一.class 的基础用法

    1.ES6 引入 Class(类)这个概念,作为对象的模板。通过 class 关键字,可以定义类。

    class Point {
      constructor(name, age) {
        this.name = name;
        this.age = age;
      }
    
      toString() {
        console.log(this.name + this.age);
      }
    }
    // ES5实现ES6同样的效果
    function Point(name, age) {
      this.name = name;
      this.age = age;
    }
    Point.prototype.toString = function() {
      console.log(this.name + this.age);
    };
    
    • ES6 类的 constructor(构造方法)函数相当于 ES5 的构造函数
    • 定义“类”的方法的时候,前面不需要加上 function 这个关键字
    • 类的所有方法都定义在类的 prototype 属性上面。
    • 类内部定义的方法,它是不可枚举的。这一点与 ES5 的行为不一致(可以枚举的)。
    // ES6
    class Point {
      constructor(x, y) {
        // ...
      }
      toString() {
        // ...
      }
    }
    Object.keys(Point.prototype);
    //[]   不可枚举的
    ES6;
    var Point = function(x, y) {
      // ...
    };
    Point.prototype.toString = function() {
      // ...
    };
    Object.keys(Point.prototype);
    // ["toString"]   可以枚举的
    

    2.constructor 方法

    • constructor 方法是类的默认方法,通过 new 命令生成对象实例时,自动调用该方法。一个类必须有
    • constructor 方法,如果没有显式定义,一个空的 constructor 方法会被默认添加。

    3.类的实例对象

    生成类的实例对象的写法,与 ES5 完全一样,也是使用 new 命令

    class Point {
      // ...
    }
    // 报错
    var point = Point(2, 3);
    // 正确
    var point = new Point(2, 3);
    

    4.Class 表达式

    const MyChild = class Child {
      toString() {
        console.log(Child.name); //name属性总是返回紧跟在class关键字后面的类名。
      }
    };
    //类的名字是MyChild而不是Child,Child只在Class内部代码可用
    let mychild = new MyChild();
    mychild.toString(); // Child
    //如果函数内部用不到Child,也可以省略
    const MyChild = class {
      // ...
    };
    

    5.Class 的静态方法

    类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前, 加上 static 关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。

    class Foo {
      static className() {
        console.log("heyushuo");
      }
    }
    Foo.className(); //heyushuo 不能通过实例调用会报错
    // 注意,如果静态方法包含this关键字,这个this指的是类,而不是实例。
    class Foo {
      static bar() {
        this.baz();
      }
      static baz() {
        console.log("hello");
      }
      baz() {
        console.log("world");
      }
    }
    Foo.bar(); // hello
    // 1.静态方法bar调用了this.baz,这里的this指的是Foo类,而不是Foo的实例,等同于调用Foo.baz。
    // 2.静态方法可以与非静态方法重名。
    // 父类的静态方法,可以被子类继承。
    class Foo {
      static classMethod() {
        return "hello";
      }
    }
    class Bar extends Foo {}
    Bar.classMethod(); // 'hello'
    

    二.类的继承

    1.Class 可以通过 extends 关键字实现继承,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多

    class Parent {
      constructor(name, age) {
        this.name = name;
        this.age = age;
      }
      toString() {
        console.log("年龄:" + this.age + "姓名:" + this.name);
      }
    }
    class Child extends Parent {
      constructor(name, age, height) {
        super(name, age); //调用父类的constructor(构造方法)
        this.height = height;
      }
      sayInfo() {
        super.toString(); // 调用父类的toString()
        console.log(`身高:${this.height}`);
      }
    }
    var person = new Child("heyushuo", 24, 180);
    person.sayInfo(); //年龄:24姓名:heyushuo   身高:180
    
    • 通过 extends 关键字 Child 继承了 Parent 的说有的属性和方法
    • 子类必须在 constructor 方法中调用 super 方法,使子类获得自己的 this 对象,否则新建实例时会报错。
    • 在子类的构造函数中,只有调用 super 之后,才可以使用 this 关键字,否则会报错。

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

    // 父类的静态方法,也会被子类继承。
    class A {
      static hello() {
        console.log("hello world");
      }
    }
    class B extends A {}
    B.hello(); // hello world
    // hello()是A类的静态方法,B继承A,也继承了A的静态方法。
    

    2.super 关键字

    super 关键字,既可以当做函数使用,也可以当做对象使用.

    super 作为函数

    • super 作为函数调用时,代表父类的构造函数。ES6 要求,子类的构造函数必须执行一次 super 函数。
    • super 虽然代表了父类 A 的构造函数,但是返回的是子类 B 的实例,即 super 内部的 this 指的是 B
    • super()只能用在子类的构造函数之中,用在其他地方就会报错。
    class A {}
    class B extends A {
      constructor() {
        super();
      }
    }
    // 注意, super虽然代表了父类A的构造函数, 但是返回的是子类B的实例,
    //即super内部的this指的是B,因此super() 在这里相当于A.prototype.constructor.call(this)。
    

    super 作为对象时

    • 在普通方法中指向父类的原型对象,在静态方法中指向父类
    • super 指向父类的原型对象,所以定义在父类实例上的方法或属性,是无法通过 super 调用的。
    • 子类普通方法中通过 super 调用父类的方法时,方法内部的this 指向当前的子类实例。
    • super 作为对象,用在静态方法之中,这时super 将指向父类,在普通方法之中指向父类的原型对象

    参考:

    阮一峰 ES6

  • 相关阅读:
    BSOJ 4490 避难向导
    【水题】求条件最大值
    【模拟】神奇的树
    【模拟】2014ACM/ICPC亚洲区北京站-A-(Curious Matt)
    【模拟】refresh的停车场
    数据结构实验之栈三:后缀式求值 (stack)
    【STL】Message Flood(set)
    【STL】完美网络(优先队列实现)
    【搜索BFS】走迷宫(bfs)
    【STL】deque双向队列(转载)
  • 原文地址:https://www.cnblogs.com/heyushuo/p/10096787.html
Copyright © 2020-2023  润新知