美文网首页
ES6时代的JavaScript面向对象编程

ES6时代的JavaScript面向对象编程

作者: Jtag特工 | 来源:发表于2017-02-14 21:31 被阅读821次

    ES6时代的JavaScript面向对象编程

    ES6带来的类语法糖

    类的定义

    ES6支持了class,extends关键字,也支持Class的静态方法,一切看起来越来越像Java开发人员所熟悉的那一套机制。

    首先看class关键字,通过class关键字,可以像Java语言定义类一样去定义对象。其构造方法为constructor方法。
    例,定义一个圆:

    class Circle {
        constructor(x,y,r){
            this.x = x;
            this.y = y;
            this.r = r;
        }
    
        area(){
            return Math.PI * this.r * this.r;
        }
    }
    
    let circle1 = new Circle(0,0,10);
    console.log(circle1.area());
    

    输出为半径为10的圆的面积:

    314.1592653589793
    

    类的继承

    ES6可以通过extends关键字来继承一个class,子类的构造函数可以通过super关键字来调用父类的构造函数。
    举例如下:

    class Sphere extends Circle {
        constructor(x,y,z,r){
            super(x,y,r);
            this.z = z;
        }
        volume() {
            return 4/3*Math.PI * this.r * this.r * this.r;
        }
    }
    

    需要说明的一点是,子类的构造函数一定要通过super关键字来调用父类的构造函数,否则不能使用this关键字。因为子类中没有this对象,要使用父类的。

    比如我们不调super,这么写:

    class Sphere2 extends Circle {
        constructor(x,y,z,r){
            this.x = x;
            this.y = y;
            this.z = z;
            this.r = r;
        }
        volume() {
            return 4/3*Math.PI * this.r * this.r * this.r;
        }
    }
    

    会是什么下场呢?答案是this未定义:

            this.x = x;
            ^
    
    ReferenceError: this is not defined
    

    静态方法

    静态方法也叫类方法,是不会被对象继承的方法。
    在Java中,对象也可以调用类的静态方法,虽然说不建议如此。在ES6的语法中,对象里根本就找不到类的方法,必须通过类来调用。

    比如我们写个获取类的一个实例的一个静态方法obtain:

    class Circle {
        constructor(x, y, r) {
            this.x = x;
            this.y = y;
            this.r = r;
        }
    
        area() {
            return Math.PI * this.r * this.r;
        }
    
        static obtain(x, y, r) {
            return new Circle(x, y, r);
        }
    }
    
    let circle2 = Circle.obtain(1, 1, 4);
    console.log(circle2.area());
    

    如果想通过对象circle2去调用obtain方法,是什么结果呢?

    let circle2 = Circle.obtain(1, 1, 4);
    console.log(circle2.area());
    
    circle2.obtain(2,2,2);
    

    答案是找不到这个方法:

    circle2.obtain(2,2,2);
            ^
    
    TypeError: circle2.obtain is not a function
    

    对象不能调用类的静态方法,但是子类会继承父类的静态方法:

    let ball2 = Sphere.obtain(1,1,1);
    

    Sphere虽然没有定义obtain,但是它继承了Circle的obtain,所以是有效的。

    静态方法可以继承也可以重载,也可以通过super来访问父类的静态方法。
    静态方法不像构造方法,不是一定要用super了,反正也没有this可以用。
    例:

    class Sphere extends Circle {
        constructor(x, y, z, r) {
            super(x, y, r);
            this.z = z;
        }
        volume() {
            return 4 / 3 * Math.PI * this.r * this.r * this.r;
        }
        static obtain(x,y,z,r){
            return new Sphere(x,y,z,r);
        }
    }
    
    let ball2 = Sphere.obtain(1,1,1);
    console.log(ball2);
    
    let ball3 = Sphere.obtain(1,1,1,1);
    console.log(ball3);
    

    输出如下:

    Sphere { x: 1, y: 1, r: undefined, z: 1 }
    Sphere { x: 1, y: 1, r: 1, z: 1 }
    

    静态属性

    ES6中没有定义静态属性。

    相关文章

      网友评论

          本文标题:ES6时代的JavaScript面向对象编程

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