es6中class介绍

责编:menVScode 2018-02-23 23:03 阅读(545)

        js语法的传统方法是通过构造函数,定义并生成新对象,是一种基于原型的面向对象系统。这种写法跟传统的面向对象语言(不如C++和Java)差异很大,很容易让新学习这门语言的人感到困惑,所以,在 ES6 中新增了类的概念,可以使用 class 关键字声明一个类,之后将这个类实例化对象。

        es5中基于原型的面向对象系统

const Mvc = function(a,b){
    this.a = a;
    this.b = b;
    return this;
}
Mvc.prototype = {
    constructor: Mvc,
    print: function(){
        console.log(this.a+' '+this.b);
    }
}

const men = new Mvc('menvs','code').print();

        基于 ES6 中 class 类,这种写法就是 ES5 写法的语法糖

class Mvc {
    constructor(a,b){
        this.a = a;
        this.b = b;
        return this;
    }
    print(){
        console.log(this.a+' '+this.b);
    }
}

const men = new Mvc('menvs','code').print();

        【1】Mvc中的constructor方法是构造方法,this关键字则代表实例对象。也就是说,ES5 的构造函数Mvc,对应ES6的Mvc这个类的构造方法。

        【2】Mvc这个类除了构造方法,还定义了一个print方法。注意,定义“类”的方法的时候,前面不需要加上function这个关键字,直接把函数定义放进去就可以了。另外,方法之间不需要逗号分隔,加了会报错。

        【3】构造函数的prototype属性,在ES6的“类”上面继续存在。而且类的所有方法都定义在类的prototype属性上面。

console.log(Mvc.prototype)
{
    constructor:(a,b)
    print:()
    __proto__:Object
}

        【4】定义在类中的方法都是不可以枚举的。

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

        【6】生成类的实例对象的写法,雨ES5完全一样,也是使用new命令。如果忘记加上new,像函数那样调用Class,将会报错的。


        class继承介绍

        在 ES6 中提供了 extends 关键字,可以很方便实现子类去继承父类。同时提供了 static 关键字,可以为类指定一些静态的方法。super 关键字,可以在子类去继承父类的时候方便的去调用父类原型身上的方法或者静态方法。

        例子html

<canvas id="canvas" style="box-shadow: 2px 2px 12px"></canvas>

        例子js

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const w=canvas.width=600;
const h=canvas.height=400;

class Ball {
    constructor(x,y,r){
        this.x = x;
        this.y = y;
        this.r = r;
        this.color = `rgb(${~~Ball.rpFn([55,255])},${~~Ball.rpFn([55,255])},${~~Ball.rpFn([55,255])})`;//加波浪号是为了去除小数部分
        return this; // 可以在实例化的时候,方便的去调用其他的方法
    }
    render(ctx){
        ctx.save();
        ctx.translate(this.x,this.y);//小球绘制坐标
        ctx.fillStyle = this.color;
        ctx.beginPath();
        ctx.arc(0,0,this.r,0,2*Math.PI);
        ctx.fill();
        ctx.restore();
        return this;
    }
    // 产生随机颜色的静态方法
    static rpFn(arr){ //使用方式:Ball.rpFn([1,10]),会产生1~10的随机数
        let max = Math.max(...arr);
        let min = Math.min(...arr);
        return Math.random()*(max-min)+min;
    }
}

// const ball01 = new Ball(100,100,30).render(ctx);

class SuperBall extends Ball{ //extends关键字使得SuperBall子类继承了Ball父类的属性和静态方法。
    constructor(x,y,r){
        //子类中调用父类的构造函数
        // super关键字:1、在子类继承父类的时候,在子类的构造函数中当作函数使用,就当于调用了父类的构造函数。
        // console.log(this) //在super调用之前,子类是没有自己的this的,this是不存在的。
        super(x,y,r)
        //在super调用之后,就相当于子类继承了父类所有的属性

        //Ball.call(this,x,y,r);//es5的写法,不过会报错;

        this.vy = SuperBall.rpFn([2,4]); //纵向速度
        this.g = SuperBall.rpFn([0.2,0.4]); //重力加速度
        this.a = 0;
        return this;
    }
    move(ctx){
        //super(); //报错,当成函数使用只能在构造函数中。
        this.y += this.vy;
        this.vy += this.g;
        let current = this.vy * -0.75;

        if(this.y+this.r >= ctx.canvas.height){
            this.y = ctx.canvas.height - this.r;
            if(Math.abs(current-this.a) < 0.01){
                return false;
            }
            this.vy = this.vy *= -0.75
        }

        ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);

        // super 第2种使用方式,是一个对象,指向的是父类的源性对象
        super.render(ctx); //会自动绑定子类的this
        return true;
    }
}

// const ball01 = new SuperBall(100,100,30).render(ctx);

let ball,timer;
canvas.onclick = function(e){
    let x = e.offsetX, y = e.offsetY;
    let r = ~~Ball.rpFn([25,55]);
    //清除画布,保证画布上只有一个小球
    ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
    ball = new SuperBall(x, y, r).render(ctx);

    ballMove()
}

function ballMove(){
    timer = window.requestAnimationFrame(ballMove);//接收动画帧的返回值

    if(!ball.move(ctx)){
        window.cancelAnimationFrame(timer);
    }
}

        子类继承父类使用 extends 关键字,为父类指定静态方法,使用 static 方法名字。

        super 在构造函数可以当作一个函数来使用,相当于调用父类的构造函数。在原型方法中,可以当作一个对象来使用,相当于父类的原型对象,并且会自动绑定this到子类上。

标签: class es6
前端交流群: MVC前端网(menvscode.com)-qq交流群:551903636

邮箱快速注册

忘记密码