一、使用关键字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()
}