ES6中的Class关键字

729 阅读4分钟

这是我参与11月更文挑战的第11天,活动详情查看:2021最后一次更文挑战

Class关键字

一、类的声明

ECMAScript 6 提供了更接近传统开发语言的写法,引人了类(Class)的概念。类作为对象的模板,只是一个语法糖。class 关键字只是让对象原型的写法更加清晰、更像面向对象的编程的语法。

示例代码如下:

// ES5 创建构造函数
function Hero() {
    this.name = '迪迦';
    this.sayMe = function () {
    console.log('this is 迪迦');
    }
}
Hero.prototype = {
    age : 19,
    job : function () {
        console.log('守护地球');
    }
}
var hero = new Hero();

// ES6创建类
class Hero {
    constructor() {
        this.name = '迪迦';
        this.sayMe = function () {
            console.log('this is 迪迦');
        }
    }
}

1. 类的声明的两种方式

(1)类的声明方式

class name [extends]{
         //class body
}
  • name : 表示当前声明的类名。

但是不同于类表达式,**类声明不允许再次声明已存在的类,**否则将会抛出一个类型错误。

(2)类的表达式方式

const MyClass = class [className][extends]{
	//class body	                                  
};

和函数表达式相同的一点是,类表达式可以是命名也可以是匿名的。如果是命名类表达式,这个名字只能在类体内部才能访问到。

示例代码如下:

/*
    1.类的声明方式
        class className{
            内部结构
        }
        * class 关键字 - 用于创建类
        * className - 用于创建的类名
*/
// class Hero {}
// 声明方式一定不允许重复声明

/*
    2.类的表达式方式
        const/let/var myClass = class [className]{
            内部结构
        }
        * class 关键字 - 用于创建类
        * myClass/ClassName - 表示创建的类名
            * myClass - 类名,用于后面的代码逻辑进行调用
            * ClassName - 类名,用于当前类的内部使用的
*/
const Hero = class hero{}
// 表达式方式运行使用var 关键字进行重复声明

2. 构造函数

构造函数(Constructor )是用于创建和初始化类中创建的一个对象的一种特殊方法。

constructor([arguments]){...}
  • 在一个类中只能有一个名为“constructor”的特殊方法。一个类中出现多次构造函数(Constructor)方法将会抛出一个SyntaxError错误。
  • 在一个构造方法中可以使用super 关键字来调用一个父类的构造方法。
  • 如果没有显式指定构造方法,则会添加默认的constructor方法。
  • 如果不指定一个构造函数( constructor )方法,则使用一个默认的构造函数( constructor ) 。
/*
    创建类 - 结构
    * 外层的类的语法结构
    * 内层的构造器的语法结构
*/
class Hero {
    // 构造器
    constructor() {
        this.name = '迪迦';
        this.sayMe = () =>{
            console.log('我是迪迦奥特曼')
        }
    }
}
let hero = new Hero();
console.log(hero.name);//迪迦
hero.sayMe();//我是迪迦奥特曼

3. getter 与 setter

与ECMAScript 5一样,在“类”的内部可以使用get 和 set 关键字,对某个属性设置存值函数和取值函数,拦截该属性的存取行为。

示例代码如下:

// ES5
// 写法一
function fn() {
    var v = 100;//局部变量
    return {
        get: function () {
            return v;
        },
        set : function (value) {
            v = value;
        }
    }
}
var obj = fn();
obj.set(1000);
console.log(obj.get());//1000

// 写法二
function fn() {
    var v = 100;
    this.get = function () {
        return v;
    }
    this.set = function (value) {
        v = value;
    }
}
var obj = new fn();
obj.set(1000);
console.log(obj.get());

// ES6
class Hero {
    constructor() {
        this.v = 100;
    }
    get getV(){
        return this.v;
    }
    set setV(value){
        this.v = value;
    }
}
var obj = new  Hero();
obj.v = 1000;
console.log(obj.v);//1000

4.不允许声明提前

声明类时,是不存在声明提前的现象的。如下代码所示:

new Foo();
class Foo{};

上述代码示例中,Foo类调用在前,声明在后。由于 ECMAScript 6 不允许类的声明提前,结果为报错。

这种规定的原因与继承有关,必须保证子类在父类之后定义。


二、静态方法

1. 语法

static 关键字为一个类定义了一个静态方法。静态方法不会在类的实例上被调用,相反被类本身调用。

static methodName() {...}
  • methodName : 表示指定类中的静态方法名称。

静态方法调用直接在类上进行,不能在类的实例上调用。


// ES6
class Hero {
    constructor() {
        this.name = '迪迦';
    }
    /!*
        在类的内部,允许定义静态方法
        * 语法结构
            static 静态方法名称(){
                方法体
            }
         * 特点 - 静态方法是不会被添加到当前类的实例(创建的对象)中
         * 调用 - 通过当前类直接调用静态方法
    *!/
    static sayMe(){
        console.log('this is 迪迦');
    }
}
// 通过Hero类创建一个hero对象
let hero = new Hero();
console.log(hero);//Hero { name: '迪迦' }

// 类名直接调用静态方法
Hero.sayMe();//this is 迪迦


// ES5 构造函数
function Hero() {
    this.name = '张无忌';
}
Hero.sayMe = function () {
    console.log('this is 迪迦');
}
var hero = new Hero();
console.log(hero);
Hero.sayMe();

2. 静态方法的调用

  • 从另一个静态方法调用

    在同一个类中的一个静态方法调用另一个静态方法,可以使用 this 关键字。

  • 从类的构造函数和其他方法调用

    静态方法不能直接在非静态方法中使用this关键字来访问。

    • 需要使用类名来调用:CLASSNAME.STATIC_METHOD_NAME()
    • 将其作为构造函数的属性来调用该方法:this.constructor.STATIC_METHOD_NAME().

两种方式示例代码如下:

class Hero{
    // 构造器 - 创建对象时,初始化的属性和方法
    constructor() {
        this.name = '迪迦';
        this.sayMe = () => {
            console.log('this is ' + this.name );
            // 在构造器中调用静态方法的话,类名直接调用
            Hero.sayYou();
        }
    }
    toString (){
        console.log('name toString:' + this.name);
    }
    static sayYou(){
        console.log('this is sayYou')
    }
    static sayHe(){
        // 当前的静态方法中,调用另一个静态方法
        this.sayYou();//this 指代当前的Hero类
    }
}
let hero = new Hero();
// console.log(hero);
hero.sayMe();
// Hero.sayYou();