標籤:重寫 find work 提升 return str objects cee ica
在 ECMAScript 6 引入的 JavaScript 類(class)是 JavaScript 現有的原型繼承的文法糖。 類並不是 JavaScript 裡加入的新的物件導向的繼承模型。JavaScript 中的類只是能讓我們用更簡潔明了的文法建立對象及處理相關的繼承。
定義類
類實際上是個“特殊的函數”,而且正如函數的定義方式有函式宣告和函數運算式兩種一樣,類的定義方式也有兩種,分別是:類聲明和類運算式。
類聲明
類聲明是定義類的一種方式,就像下面這樣,使用 class 關鍵字後跟一個類名(這裡是 Polygon),就可以定義一個類。
1 class Polygon {2 constructor(height, width) {3 this.height = height;4 this.width = width;5 }6 }
變數提升
類聲明和函式宣告不同的一點是,函式宣告存在變數提升現象,而類聲明不會。也就是說,你必須先聲明類,然後才能使用它,否則代碼會拋出 ReferenceError 異常,像下面這樣:
1 var p = new Polygon(); // ReferenceError2 3 class Polygon {}
類運算式
類運算式是定義類的另外一種方式。在類運算式中,類名是可有可無的。如果定義了類名,則該類名只有在類體內部才能訪問到。
1 // 匿名的 2 var Polygon = class { 3 constructor(height, width) { 4 this.height = height; 5 this.width = width; 6 } 7 }; 8 9 // 命名的10 var Polygon = class Polygon {11 constructor(height, width) {12 this.height = height;13 this.width = width;14 }15 };
注意: 類運算式和類聲明一樣也不會有提升的現象。
類體和方法定義
類的成員需要定義在一對花括弧 {} 裡,花括弧裡的代碼和花括弧本身組成了類體。類成員包括類構造器和類方法(包括靜態方法和執行個體方法)。
strict 模式
類體中的代碼都強制在strict 模式中執行。
構造器
構造器方法是一個特殊的類方法,其用於建立和初始化對象(用該類產生的)。一個類只能擁有一個名為constructor 的方法,否則會拋出 SyntaxError 異常。
在子類的構造器中可以使用 super 關鍵字調用父類的構造器。
原型方法
參見方法定義。
1 class Polygon { 2 constructor(height, width) { 3 this.height = height; 4 this.width = width; 5 } 6 7 get area() { 8 return this.calcArea() 9 }10 11 calcArea() {12 return this.height * this.width;13 }14 }15 const square = new Polygon(10, 10);16 17 // 10018 console.log(square.area);
靜態方法
static 關鍵字用來定義類的靜態方法。靜態方法是指那些不需要對類進行執行個體化,使用類名就可以直接存取的方法,需要注意的是靜態方法不能被執行個體化的對象調用。靜態方法經常用來作為工具函數。
1 class Point { 2 constructor(x, y) { 3 this.x = x; 4 this.y = y; 5 } 6 7 static distance(a, b) { 8 const dx = a.x - b.x; 9 const dy = a.y - b.y;10 11 return Math.sqrt(dx*dx + dy*dy);12 }13 }14 15 const p1 = new Point(5, 5);16 const p2 = new Point(10, 10);17 18 console.log(Point.distance(p1, p2));
使用
extends 建立子類
extends 關鍵字可以用在類聲明或者類運算式中來建立一個繼承了某個類的子類。
1 class Animal { 2 constructor(name) { 3 this.name = name; 4 } 5 6 speak() { 7 console.log(this.name + ‘ makes a noise.‘); 8 } 9 }10 11 class Dog extends Animal {12 speak() {13 console.log(this.name + ‘ barks.‘);14 }15 }16 17 var d = new Dog(‘Mitzie‘);18 // ‘Mitzie barks.‘19 d.speak();
同樣也可以用於原有的原型繼承的“類”:
1 function Animal (name) { 2 this.name = name; 3 } 4 Animal.prototype.speak = function () { 5 console.log(this.name + ‘ makes a noise.‘); 6 } 7 8 class Dog extends Animal { 9 speak() {10 super.speak();11 console.log(this.name + ‘ barks.‘);12 }13 }14 15 var d = new Dog(‘Mitzie‘);16 d.speak();
需要注意的是類不能繼承一般(非構造的)對象。如果你想要建立的類繼承某個一般對象的話,你要使用 Object.setPrototypeOf():
1 var Animal = { 2 speak() { 3 console.log(this.name + ‘ makes a noise.‘); 4 } 5 }; 6 7 class Dog { 8 constructor(name) { 9 this.name = name;10 }11 speak() {12 super.speak();13 console.log(this.name + ‘ barks.‘);14 }15 }16 Object.setPrototypeOf(Dog.prototype, Animal);17 18 var d = new Dog(‘Mitzie‘);19 d.speak();
Species
你可能想要數組類 MyArray 返回的是 Array 對象。這個 species 模式能讓你重寫預設的構造器。
例如,當使用像 map() 這樣的方法來返回預設的構造器時,你想要這個方法返回父級的 Array 對象,而不是MyArray 對象。Symbol.species 能實現:
1 class MyArray extends Array {2 // Overwrite species to the parent Array constructor3 static get [Symbol.species]() { return Array; }4 }5 var a = new MyArray(1,2,3);6 var mapped = a.map(x => x * x);7 8 console.log(mapped instanceof MyArray); // false9 console.log(mapped instanceof Array); // true
使用
super 引用父類
super 關鍵字可以用來調用其父類的構造器或者類方法
class Cat { constructor(name) { this.name = name; } speak() { console.log(this.name + ‘ makes a noise.‘); }}class Lion extends Cat { speak() { super.speak(); console.log(this.name + ‘ roars.‘); }}
Mix-ins
抽象子類或者 mix-ins 是類的模板。 一個 ECMAScript 類只能僅有一個父類,所以想要從工具類來多重繼承的行為是不可能的。子類繼承的只能是父類提供的功能性。
在 ECMAScript 裡一個將父類作為輸入且將其子類作為輸出的函數可以用來實現 mix-ins:
1 var calculatorMixin = Base => class extends Base {2 calc() { }3 };4 5 var randomizerMixin = Base => class extends Base {6 randomize() { }7 };
使用 mix-ins 的類可以像下面這樣寫:
1 class Foo { }2 class Bar extends calculatorMixin(randomizerMixin(Foo)) { }
相關:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Classes
ECMAScript 6 引入的 JavaScript 類(class)--類同java class