class (類)做爲對象的模板被引入,能夠經過 class 關鍵字定義類。類簡要說明
類的本質是function,是基本原型繼承的語法糖。因此,JS中繼承的模型是不會被改變的。
類既然是函數,那與函數有何不一樣呢?咱們爲何要使用類呢?
有時間,先看一下MDN odhtml
首先class關鍵字,而後是類的名字,其它部分的語法,相似於對象字面量方法的簡寫形式,但不須要在各元素之間使用逗號分隔。es6
class HelloClass { constructor(greeting) { this.greeting = greeting; } sayGreeting(){ console.log(this.greeting); } } let hello = new HelloClass('Hello'); hello.sayGreeting(); // Hello console.log(hello instanceof HelloClass); // true console.log(hello instanceof Object); // true console.log(typeof HelloClass); // function console.log(typeof HelloClass.prototype.sayGreeting); // function
分析:函數
與之等價的ES5聲明this
let HelloClass = (function(){ "use strict"; const HelloClass = function(greeting) { if (typeof new.target === 'undefined') { throw new Error("必須經過關鍵字new調用構造函數"); } this.greeting = greeting; Object.defineProperty(HelloClass.prototype, "sayGreeting", { value: function() { if (typeof new.target !== 'undefined') { throw new Error("不可以使用關鍵字new調用構造函數"); } console.log(this.greeting); }, enumerable: false, writable: true, configurable: true }); } return HelloClass; }()); let hello = new HelloClass('Hello'); hello.sayGreeting(); console.log(hello instanceof HelloClass); console.log(hello instanceof Object); console.log(typeof HelloClass); console.log(typeof HelloClass.prototype.sayGreeting);
類表達式能夠是被命名的或匿名的。賦予一個命名類表達式的名稱是類的主體的本地名稱。和function的表達式相似,但不會像函數聲名或和函數表達式同樣被提高。prototype
/* 匿名類 */ let Rectangle = class { constructor(height, width) { this.height = height; this.width = width; } }; console.log(typeof Rectangle); // function
/* 命名的類 */ let Rectangle = class Rectangle1 { constructor(height, width) { this.height = height; this.width = width; } }; console.log(typeof Rectange); // function console.log(typeof Rectange1); // undefined
在JS中,函數爲一等「公民」,能夠傳入函數,也能夠從函數中返回,還能夠賦值給變量的值。類也是JS中的一等公民。code
- getter - setter
class Rectangle { // constructor constructor(height, width) { this.height = height; this.width = width; } // Getter get area() { return this.calcArea() } // Method calcArea() { return this.height * this.width; } } const square = new Rectangle(10, 10); console.log(square.area); // 100
const methodName = "sayGreeting"; class HelloClass { constructor(greeting) { this.greeting = greeting; } [methodName]() { console.log(this.greeting); } } let hello = new HelloClass('Hello'); hello.sayGreeting(); // Hello hello[methodName](); // Hello
可計算訪問器屬性。orm
const propertyName = "greeting"; class HelloClass { constructor() { } get [propertyName]() { return this.greetingStr; } set [propertyName](value) { this.greetingStr = value; } } let hello = new HelloClass(); hello.greeting = 'Hello'; console.log(hello.greeting);
class NormClass { *createIterator() { yield 1; yield 2; yield 3; } } let instance = new NormClass(); let iterator = instance.createIterator(); console.log(iterator.next()); // { value: 1, done: false } console.log(iterator.next()); // { value: 2, done: false } console.log(iterator.next()); // { value: 3, done: false } console.log(iterator.next()); // { value: undefined, done: true }
爲類定義默認迭代器。htm
class Collection { constructor() { this.items = []; } *[Symbol.iterator]() { yield *this.items.values(); } } var coll = new Collection(); coll.items.push(1); coll.items.push(2); coll.items.push(3); for (let i of coll) { console.log(i); } // 1 // 2 // 3
class Animal { speak() { return this; } static eat() { return this; } } let obj = new Animal(); console.log(obj.speak()); // Animal {} let speak = obj.speak; console.log(speak()); // undefined console.log(Animal.eat()); // class Animal let eat = Animal.eat; console.log(eat()); // undefined