JavaScript原型对象6-ES6的类class

303 阅读2分钟

一、使用关键字class

在ES6引入新的关键字class,它提供了一种更为优雅的创建对象和实现继承的方式。

但底层仍然是基于原型的实现

class Ninja {
    constructor(name) {
        this.name = name;
    }
    swingSword() {
        return true
    }
}

var ninja = new Ninja("Yoshi")
assert(ninja instanceof Ninja, "our ninja is a Ninja")
assert(ninja.name === "Yoshi", "named Yoshi")
assert(ninja.swingSword(), "and he can swing a sword")

class语法糖

虽然ES6引入关键字class,但底层仍然是基于原型的实现

class只是语法糖,使得在JavaScript模拟类的代码更为简洁

// 上面的class代码可转换为如下ES5的代码
function Ninja(name) {
    this.name = name;
}
Ninja.prototype.swingSword = function() {
    return true;
}

静态方法

之前的示例展示了如何定义所有实例对象可访问的对象方法(原型方法)

除了对象方法之外,类级别的静态方法怎么实现?

// 在ES6中的静态方法
class Ninja {
    constructor(name, level) {
        this.name = name
        this.level = level;
    }
    swingSword() {
        return true;
    }
    static compare(ninja1, ninja2) {
        return ninja1.level - ninja2.level
    }
}

var ninja1 = new Ninja("Yoshi", 4)
var ninja2 = new Ninja("Natttori", 3)
assert(!("compare" in ninja1) && ("compare" in ninja2), "A ninja instance donsn't know how to compare")
assert(Ninja.compare(ninja1, ninja2) > 0, "The Ninja class can do the comparision")
assert(!("swingSword" in Ninja), "The Ninja class connot swing a sword")


// ES6中的静态方法,对应ES5的代码
function Ninja() {}
Ninja.compare = function(ninj1, ninja2) {...}

二、实现继承

在ES6之前的版本中实现继承是一件痛苦的事

function Person() {}
Person.prototype.dance = function() {}
function Ninja() {}
Ninja.prototype = new Person();

Object.defineProperty(Ninja.prototype, "constructor", {
    enumerable: false,
    value: Ninja,
    writable: true
})

在ES6中实现继承

class Person {
    constructor(name) {
        this.name = name;
    }
    dance() {
        return true
    }
}

class Ninja extends Person {
    constructor(name, weapon) {
        super(name);   // 关键字super,调用基类构造函数
        this.weapon = weapon
    }
    wieldWeapon() {
        return true
    }
}
var person = new Person("Bob")
assert(person instanceof Person, "A person's a person")
assert(person.dance(), "A person can dance")
assert(person.name === "Bob", "we can call it by name")
assert(!(person instanceof Ninja), "But it's not a Ninja")
assert(!("wieldWeapon" in persion), "And it cannot wield a weapon")

var ninja = new Ninja("Yoshi", "Wakizashi")
assert(ninja instanceof Ninja, "A ninja's ninja")
assert(ninja.wieldWeapon(), "The can wield a weapon")
assert(ninja instance of Person, "But it's a also a person")
assert(ninja.name == "Yoshi", "That has a name")
assert(ninja.dance(), "And enjoys dancing")

小结习题

将以下ES6代码转为ES5

class Warrior {
    constructor(weapon) {
        this.weapon = weapon
    }
    wield() {
        return "Wielding" + this.weapon
    }
    static duel(warrior1, warrior2) {
        return warrior1.wield() + " " + warrior2.wield()
    }
}

转换ES5

function Warrior(weapon) {
    this.weapon = weapon
}
Warriro.prototype.wield = function () {
 return "Wielding" + this.weapon 
}
Warrior.duel = functionduel(warrior1, warrior2) {
    return warrior1.wield() + " " + warrior2.wield()
}