javascript
[转]JavaScript ES6 class指南
[轉(zhuǎn)]JavaScript ES6 class指南
前言
EcmaScript 2015 (又稱ES6)通過(guò)一些新的關(guān)鍵字,使類成為了JS中一個(gè)新的一等公民。但是目前為止,這些關(guān)于類的新關(guān)鍵字僅僅是建立在舊的原型系統(tǒng)上的語(yǔ)法糖,所以它們并沒(méi)有帶來(lái)任何的新特性。不過(guò),它使代碼的可讀性變得更高,并且為今后版本里更多面向?qū)ο蟮男绿匦源蛳铝嘶A(chǔ)。
這樣做的原因是為了保證向后兼容性。也就是,舊代碼可以在不做任何hack的情況下,與新代碼同時(shí)運(yùn)行。
定義類
讓我們回想一下在ES5中定義一個(gè)類的方式。通過(guò)不是很常用的Object.defineProperty方法,我可以定義一些只讀的屬性。
function Vehicle(make, year) {Object.defineProperty(this, 'make', {get: function() { return make; }});Object.defineProperty(this, 'year', {get: function() { return year; }}); }Vehicle.prototype.toString = function() {return this.make + ' ' + this.year; }var vehicle = new Vehicle('Toyota Corolla', 2009);console.log(vehicle.make); // Toyota Corolla vehicle.make = 'Ford Mustang'; console.log(vehicle.toString()) // Toyota Corolla 2009很簡(jiǎn)單,我們定義了一個(gè)有兩個(gè)只讀屬性和一個(gè)自定義toString方法的Vehicle類。讓我們?cè)贓S6中來(lái)做一樣的事情:
class Vehicle {constructor(make, year) {this._make = make;this._year = year;}get make() {return this._make;}get year() {return this._year;}toString() {return `${this.make} ${this.year}`;} }var vehicle = new Vehicle('Toyota Corolla', 2009);console.log(vehicle.make); // Toyota Corolla vehicle.make = 'Ford Mustang'; console.log(vehicle.toString()) // Toyota Corolla 2009類聲明
在ES6中,有兩個(gè)聲明類的方式。第一種方法叫作 類聲明,這也是我們?cè)谏鲜隼又惺褂玫姆绞健?/p> class Vehicle {hello() {console.log('nice to meet you');} }
有一個(gè)需要注意的地方是,類聲明與函數(shù)聲明不同,它不會(huì)被提升(hoisted)。例如,以下的代碼工作正常:
console.log(helloWorld());function helloWorld() {return "Hello World"; }但是,以下代碼會(huì)拋出一個(gè)異常:
var vehicle = new Vehicle();class Vehicle { }類表達(dá)式
另一個(gè)定義類的方式叫做 類表達(dá)式。它與函數(shù)表達(dá)式的運(yùn)行方式完全一樣。一個(gè)類表達(dá)式可以是具名的也可以是匿名的。
var Vehicle = class { }var Vehicle = class VehicleClass {constructor() {// VehicleClass is only available inside the class itself} }console.log(VehicleClass); // throws an exception靜態(tài)方法
static關(guān)鍵字是ES6的另一個(gè)語(yǔ)法糖,它使靜態(tài)方法聲明也成為了一個(gè)一等公民。在ES5中,靜態(tài)方法就像是構(gòu)造函數(shù)的一個(gè)屬性。
function Vehicle() {// ... }Vehicle.compare = function(a, b) {// ... }在使用了新的static關(guān)鍵字后:
class Vehicle {static compare(a, b) {// ...} }在底層,JavaScript所做的,也只是將這個(gè)方法添加為Vehicle構(gòu)造函數(shù)的一個(gè)屬性。值得注意的是,你也可以用同樣的語(yǔ)法為類添加靜態(tài)屬性。
類繼承
舊的原型繼承有時(shí)看起來(lái)讓人非常頭疼。ES6中新的extends關(guān)鍵字解決了這個(gè)問(wèn)題。在ES5,我們是這么做的:
function Motorcycle(make, year) {Vehicle.apply(this, [make, year]); }Motorcycle.prototype = Object.create(Vehicle.prototype, {toString: function() {return 'Motorcycle ' + this.make + ' ' + this.year;} });Motorcycle.prototype.constructor = Motorcycle;使用的新的extends關(guān)鍵字,看上去就清晰多了:
class Motorcycle extends Vehicle {constructor(make, year) {super(make, year);}toString() {return `Motorcycle ${this.make} ${this.year}`;} }super關(guān)鍵字也可以用于靜態(tài)方法:
class Vehicle {static compare(a, b) {// ...} }class Motorcycle extends Vehicle {static compare(a, b) {if (super.compare(a, b)) {// ...}} }上一個(gè)例子也展示了新的super關(guān)鍵字的用法。當(dāng)你想要調(diào)用父類的函數(shù)時(shí),這個(gè)關(guān)鍵字就顯得十分好用。
在想要調(diào)用父類的構(gòu)造函數(shù)時(shí),你可以簡(jiǎn)單地將super關(guān)鍵字視作一個(gè)函數(shù)使用,如super(make, year)。對(duì)于父類的其他函數(shù),你可以將super視作一個(gè)對(duì)象,如super.toString()。例子:kk:super指向原型對(duì)象
class Motorcycle extends Vehicle {toString() {return 'Motorcycle ' + super.toString();} }可被計(jì)算的方法名
當(dāng)在class中聲明屬性時(shí),定義屬性名時(shí),你可以使用表達(dá)式。這個(gè)語(yǔ)法特性在一些ORM類庫(kù)中將會(huì)非常流行。例子:
function createInterface(name) {return class {['findBy' + name]() {return 'Found by ' + name;}} }const Interface = createInterface('Email'); const instance = new Interface();console.log(instance.findByEmail());最后
在當(dāng)前,使用class關(guān)鍵字來(lái)聲明類,而不使用原型,獲得的僅僅是語(yǔ)法上的優(yōu)勢(shì)。但是,這個(gè)是一個(gè)適應(yīng)新語(yǔ)法和新實(shí)踐的好開始。JavaScript每天都在變得更好,并且通過(guò)class關(guān)鍵字,可以使各種工具更好得幫助你。
總結(jié)
以上是生活随笔為你收集整理的[转]JavaScript ES6 class指南的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Vigen#232;re密码
- 下一篇: 菜单开源库装逼大全