javascript
[转]JavaScript ES6 class指南
[轉]JavaScript ES6 class指南
前言
EcmaScript 2015 (又稱ES6)通過一些新的關鍵字,使類成為了JS中一個新的一等公民。但是目前為止,這些關于類的新關鍵字僅僅是建立在舊的原型系統上的語法糖,所以它們并沒有帶來任何的新特性。不過,它使代碼的可讀性變得更高,并且為今后版本里更多面向對象的新特性打下了基礎。
這樣做的原因是為了保證向后兼容性。也就是,舊代碼可以在不做任何hack的情況下,與新代碼同時運行。
定義類
讓我們回想一下在ES5中定義一個類的方式。通過不是很常用的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很簡單,我們定義了一個有兩個只讀屬性和一個自定義toString方法的Vehicle類。讓我們在ES6中來做一樣的事情:
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中,有兩個聲明類的方式。第一種方法叫作 類聲明,這也是我們在上述例子中使用的方式。
class Vehicle {hello() {console.log('nice to meet you');} }有一個需要注意的地方是,類聲明與函數聲明不同,它不會被提升(hoisted)。例如,以下的代碼工作正常:
console.log(helloWorld());function helloWorld() {return "Hello World"; }但是,以下代碼會拋出一個異常:
var vehicle = new Vehicle();class Vehicle { }類表達式
另一個定義類的方式叫做 類表達式。它與函數表達式的運行方式完全一樣。一個類表達式可以是具名的也可以是匿名的。
var Vehicle = class { }var Vehicle = class VehicleClass {constructor() {// VehicleClass is only available inside the class itself} }console.log(VehicleClass); // throws an exception靜態方法
static關鍵字是ES6的另一個語法糖,它使靜態方法聲明也成為了一個一等公民。在ES5中,靜態方法就像是構造函數的一個屬性。
function Vehicle() {// ... }Vehicle.compare = function(a, b) {// ... }在使用了新的static關鍵字后:
class Vehicle {static compare(a, b) {// ...} }在底層,JavaScript所做的,也只是將這個方法添加為Vehicle構造函數的一個屬性。值得注意的是,你也可以用同樣的語法為類添加靜態屬性。
類繼承
舊的原型繼承有時看起來讓人非常頭疼。ES6中新的extends關鍵字解決了這個問題。在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關鍵字,看上去就清晰多了:
class Motorcycle extends Vehicle {constructor(make, year) {super(make, year);}toString() {return `Motorcycle ${this.make} ${this.year}`;} }super關鍵字也可以用于靜態方法:
class Vehicle {static compare(a, b) {// ...} }class Motorcycle extends Vehicle {static compare(a, b) {if (super.compare(a, b)) {// ...}} }上一個例子也展示了新的super關鍵字的用法。當你想要調用父類的函數時,這個關鍵字就顯得十分好用。
在想要調用父類的構造函數時,你可以簡單地將super關鍵字視作一個函數使用,如super(make, year)。對于父類的其他函數,你可以將super視作一個對象,如super.toString()。例子:kk:super指向原型對象
class Motorcycle extends Vehicle {toString() {return 'Motorcycle ' + super.toString();} }可被計算的方法名
當在class中聲明屬性時,定義屬性名時,你可以使用表達式。這個語法特性在一些ORM類庫中將會非常流行。例子:
function createInterface(name) {return class {['findBy' + name]() {return 'Found by ' + name;}} }const Interface = createInterface('Email'); const instance = new Interface();console.log(instance.findByEmail());最后
在當前,使用class關鍵字來聲明類,而不使用原型,獲得的僅僅是語法上的優勢。但是,這個是一個適應新語法和新實踐的好開始。JavaScript每天都在變得更好,并且通過class關鍵字,可以使各種工具更好得幫助你。
總結
以上是生活随笔為你收集整理的[转]JavaScript ES6 class指南的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Vigen#232;re密码
- 下一篇: gradle idea java ssm