阅读 492

ES6新特性class类

这是我参与8月更文挑战的第8天,活动详情查看:8月更文挑战

类是什么

Es6新增的类其实就是基于原型机制的语法糖,类的语法可以让开发者更好的定义向后兼容的类,不仅可以继承内置类型,还可以继承自定义类型。

如何定义类

定义类有俩种主要方式:类声明和类表达式,这俩种方式都使用class关键字和大花括号。 与构造函数一样,编程风格建议类名的首字母大写。程序员约定俗成的。

     //类声明
    class Person {};
    //表达式类
    const Animal = class {};
复制代码

注意:在类里面函数声明(Var)不能提升作用域,而且类受块作用域限制。

类与构造函数区别

调用类构造函数必须使用new操作符,而普通构造函数如果不使用new调用,就会以全局的this(window)作为内部对象。调用类构造函数时如果不使用new就会抛出错误。

    class Person {};
    function Person1(){};
    let p = Person();//Uncaught TypeError: Class constructor Person cannot be invoked without 'new'at
    let p1 = Person1();
复制代码

迭代器和生成器方法

类定义语支持在原型和类本身上定义生成器方法。

    class Person {
        //在原型上定义生成器
        *nameIterator (){
            yield 'jackson';
            yield 'bear';
        }

        //在类上定义生成器
        static *colorIterator(){
            yield 'blue';
            yield 'green';
        }
    };
    //类
    let p = new Person();
    let names = p.nameIterator();
    console.log(names.next().value);//jackson
    console.log(names.next().value);//bear
    //原型
    let colors = Person.colorIterator();
    console.log(colors.next().value);//blue
    console.log(colors.next().value);//green
复制代码

类的继承

Es6新特性中比较出色的就是原生支持类继承机制,虽然类继承是使用的新语法,但是依据的还是原型链

1. 继承基础

Es6支持单继承,使用extends关键字,就可以继承任何拥有 construct 和原型对象。这不仅可以继承一个类,也可以继承普通的构造函数。

     class Exten {};
    //继承类
    class Bus extends Exten {};
    let a = new Bus();
    console.log(a instanceof Bus); //true
    console.log(a instanceof Exten); //true
    

    function Person(){};
    //继承普通构造函数
    class Eng extends Person {};
    let b = new Eng();
    console.log(b instanceof Eng); //true
    console.log(b instanceof Person); //true
复制代码

2.构造函数、HomeObject、Super

派生类的方法可以通过super关键字来引用他们的原型,(super只能在派生类中使用)。在类构造函数中使用super可以调用父类构造函数。

    class Vehicle {
        constructor() {
            this.hasEngine = true;
        }
    }
    class Bus extends Vehicle {
        constructor() {
            // 不要在调用 super()之前引用 this,否则会抛出 ReferenceError
            super(); // 相当于 super.constructor()
            console.log(this instanceof Vehicle); // true
            console.log(this); // Bus { hasEngine: true }
        }
    }
    new Bus();
复制代码

image.png

注意 ES6 给类构造函数和静态方法添加了内部特性HomeObject,这个特性是一个指针,指向定义该方法的对象。这个指针是自动赋值的,而且只能在 JavaScript 引擎内部 访问。super 始终会定义为HomeObject的原型。

使用super要注意的问题

  1. super 只能在派生类构造函数和静态方法中使用。
  2. 不能单独引用 super 关键字,要么用它调用构造函数,要么用它引用静态方法。
  3. 调用 super()会调用父类构造函数,并将返回的实例赋值给 this。
  4. super()的行为如同调用构造函数,如果需要给父类构造函数传参,则需要手动传入。
  5. 如果没有定义类构造函数,在实例化派生类时会调用 super(),而且会传入所有传给派生类的参数。
  6. 在类构造函数中,不能在调用 super()之前引用 this。
  7. 如果在派生类中显式定义了构造函数,则要么必须在其中调用 super(),要么必须在其中返回一个对象。

3.继承内置类型

Es6为类继承内置引用类型提高了比较流程的机制,我们可以更方便扩展内置类型。 我们写一个去掉偶数。

     class SuperArray extends Array {}
    let a1 = new SuperArray(1, 2, 3, 4, 5);
    let a2 = a1.filter(x => !!(x % 2))
    console.log(a1); // [1, 2, 3, 4, 5]
    console.log(a2); // [1, 3, 5]
    console.log(a1 instanceof SuperArray); // true
    console.log(a2 instanceof SuperArray); // true
复制代码

Es6的Class绝大部分功能,ES5都可以做到,但是新的class写法只是让语法更加清晰,更像面向对象编程的语法。

文章分类
前端