ES6之类语法(Classes)

类语法(Classes)

  目录:


基本定义语法

  用法:class name { ... }

class People{
    constructor(name, sex){
        this.name = name;
        this.sex = sex;
    }

    say(){
        console.log(`hello! I am ${this.name}.`);
    }
}


const kobe = new People('kobe', 'man');
kobe.say();  // hello! I am kobe.

继承语法

  用法:class SubClass extends superClass {}

class Point2D{
    constructor(x, y){
        this.x = x;
        this.y = y;
    }

    toString(){
        return `(${this.x}, ${this.y})`;
    }
}

class Point3D extends Point2D{
    constructor(x, y, z){
        super(x, y);
        this.z = z;
    }

    toString(){
        return `(${this.x}, ${this.y}, ${this.z})`;
    }
}



  ES2015 的继承语法同样可以将以前使用的构建函数模拟的类作为父类来继承,而并非只有 class 语法定义的类才可以使用。

function Cat(){
    Cat.prototype.climb = function(){
        return "I can climb";
    }
    Cat.prototype.yell = function(){
        return "Meow";
    }
}

class Tiger extends Cat{
    yell(){
        return "Aoh";
    }
}

const tiger = new Tiger();
console.log(tiger.yell());  //Aoh
console.log(tiger.climb()); //I can climb



  需要非常注意的是,如果一个子类继承了一个父类,那么在子类的 constructor 构造函数中必须使用 super 函数调用父类的构造函数后才能在子类的 constructor 构造函数中使用 this ,否则会报出 this is not defined 的错误。

class Foo{
}

class Bar extends Foo{
    constructor(){
        this.property = 1;
    }
}

new Bar();  // ReferenceError: this is not defined

这个问题在除 constructor 构造函数以外的方法中并不会出现,即便在子类的构造函数中并没有调用 super 函数,在其他方法中依然可以调用 this 来指向当前实例


Getter/Setter

const List = {
    _array: [],

    set new(value){
        this._array.push(value);
    },

    get last(){
        return this._array[0];
    },

    get value(){
        return this._array;
    }
}
List.new = 1;
List.new = 2;
List.new = 3;
console.log(List.last);     // 1
console.log(List.value);    // [1, 2, 3]

静态方法

  用法:class Name { static fn() { ... } }

class People{
    constructor(number){
        this.number = number;
    }

    say(){
        console.log(`hello! I am No.${this.number}`);
    }

    static extend(constructor, ..._args){
        return class extends People{
            constructor(...args){
                super(..._args);
                constructor.call(this, ...args);
            }
        }
    }
}


const Player = People.extend(function(name){
    this.name = name;
}, 24);

const kobe = new Player("Kobe");
kobe.say();     // hello! I am No.24
console.log(kobe.name);     // Kobe

注意事项

  ES6的类语法虽然可以与以前的原型一起使用,但是他们之间也是有一定区别的
  函数有两种定义方法:声明式定义式

// 声明式
function Foo(){}
// 定义式
const Bar = function (){}

  而声明式的函数定义是可以被提升的(hoisting),即在声明式函数所在的作用域开始执行时,无论是否已经执行到这个函数的代码,都可以对这个函数进行访问和使用。

const val = (function(){
    return fn();

    function fn(){   // fn would be hoisted
        return 'foobar'
    }
})();

console.log(val);   // foobar

  这个特性同样适用于利用原型定义的类,但对于 ES6 的类语法来说这个特性是无效的。

const point = new Point(1, 2);   // ReferenceError

class Point{
    constructor(x = 0, y = 0){
        this.x = x;
        this.y = y;
    }
}

  这是因为从逻辑角度上看,类的继承必须是单向的,不可能出现 A 类继承于 B 类的同时 B 类也继承于 A 类的现象,这就意味着,父类必须在子类定义之前被定义。


遗憾和期望

  1. 不支持私有属性(private)。
  2. 不支持实例属性,但目前可以通过 Getter/Setter 实现。
  3. 不支持多重继承。
  4. 暂时没有类似协议(Protocol)和接口(Interface)等的概念。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值