美文网首页
ES6中的class类

ES6中的class类

作者: _hider | 来源:发表于2021-02-18 15:00 被阅读0次

    参考bilibili视频itstrive老师的课程(视频地址)

    ES5中,需要用构造函数和原型链来模拟面向对象的实现。如下例:

    function Person(name) {
        this.name = name;
    };
    Person.prototype.showName = function () {
        console.log("你好,我的名字叫" + this.name);
    };
    var don = new Person("don");
    don.showName();
    

    ES6中,class类作为对象的模板被引入,可以通过 class关键字定义类,它的本质还是function。可以看作一个语法糖,让对象原型的写法更加清晰、更像面向对象编程,将上例用class来写的话如下:

    class Person {
        constructor(name) {
            this.name = name;
        }
        showName() {
            console.log("你好,我的名字叫" + this.name);
        }
    }
    const don = new Person("don");
    don.showName();
    
    一、类的两种声明方式

    要注意的是类的命名首字母大写,类的声明方式除了以上class加上类名的声明式外,还有表达式声明:

    class Person {
        constructor(name) {
            ...
        }
    };
    

    不过常用的话还是类的声明式。

    二、类不存在变量提升

    ES6中的letconst都去除了变量提升机制,同样class也是。

    const don = new Person("don"); //Uncaught ReferenceError: Cannot access 'Person' before initialization
    don.showName();
    class Person {
        constructor(name) {
            this.name = name;
        }
        showName() {
            console.log("你好,我的名字叫" + this.name);
        }
    };
    
    三、类中的this

    正常情况下访问class中的this都指向的是class类的本身,也有特殊情况,如下:

    class Person {
        constructor(name) {
            this.name = name;
        }
        showName() {
            console.log("this指向的是" + this); //this指向的是undefined
            console.log("你好,我的名字叫" + this.name);
        }
    };
    const don = new Person("don");
    const { showName } = don;
    showName();
    

    上例中,实例化完Person后赋值给变量don,再将don解构出showName,然后直接调用showName函数,这里就会有问题了,因为jsthis指向是谁调用就指向谁,本例中,showName函数没有被任何对象调用,理应this指向window,不过因为ES6默认遵循严格模式,所以输出undefined。那应该如何解决这个this指向问题呢?

    class Person {
        constructor(name) {
            this.name = name;
            this.showName = this.showName.bind(this);
        }
        showName() {
            console.log("你好,我的名字叫" + this.name);
        }
    };
    const don = new Person("don");
    const { showName } = don;
    showName();
    

    只要在构造函数中将showName函数的this事先绑定好就可以了。

    四、getter和setter

    getter是存值的时候调用的,setter是设置值的时候调用的。

    class Person {
        constructor() {}
        get name() {
            return this._name;
        }
        set name(value) {
            this._name = value;
        }
    };
    const don = new Person();
    don.name = "don";
    console.log(don.name);
    

    设置值的时候,比如don.name = "don"会触发setter,当console.log(don.name);获取的时候会触发getter

    五、类的静态方法

    class本身方法,即直接定义在类内部的方法,不需要实例化。 ES6中规定,Class 内部只有静态方法,没有静态属性。声明一个类的静态方法需要用static关键字。

    class Person {
        constructor(name) {
            this.name = name;
        }
        showName() {
            console.log("你好,我的名字叫" + this.name);
        }
        static showAge() {
            console.log("你好,我的年龄是18");
        }
    }
    Person.showAge();
    
    六、类的继承
    function Person(name) {
        this.name = name;
    }
    Person.prototype.showName = function () {
        console.log("你好,我的名字叫" + this.name);
    };
    
    function Student(name, age) {
        Person.call(this, name);
        this.age = age;
    };
    Student.prototype = new Person();
    var don = new Student("don", 28);
    don.showName();
    

    以上是ES5的继承,即原型链继承,Student继承自Person,继承实现需要2个步骤:

    1. Student构造函数中调用Person函数并通过手动修改thisPerson的属性添加到Student
    2. Person实例化对象赋值给Studentprototype

    接下来看下ES6又是怎么实现的:

    class Person {
        constructor(name) {
            this.name = name;
        }
        showName() {
            console.log("你好,我的名字叫" + this.name);
        }
    }
    
    class Student extends Person {
        constructor(name, age) {
            super(name);
            this.age = age;
        }
    }
    
    var don = new Student("don", 28);
    

    ES6中需要通过extends关键字来实现继承父级,在子类constructor执行super函数表示执行父类的constructor

    在继承中,父类有个showName函数,如果子类也想有个showName函数并且希望父类的showName也可以执行,该怎么处理?

    class Person {
        constructor(name) {
            this.name = name;
        }
        showName() {
            console.log("你好,父类的名字叫" + this.name);
        }
    }
    
    class Student extends Person {
        constructor(name, age) {
            super(name);
            this.age = age;
        }
        showName() {
            super.showName();
            console.log("你好,子类的名字叫" + this.name);
        }
    }
    
    var don = new Student("don", 28);
    don.showName();
    

    主要借助super来实现,super也可以在子类的函数中调用,表示父类本身。

    相关文章

      网友评论

          本文标题:ES6中的class类

          本文链接:https://www.haomeiwen.com/subject/kxygxltx.html