起源
js 從建立之初就不支援類,也沒有把類繼承作為定義相似物件以及關聯物件的主要方式,這讓不少開發者感到困惑。而從 es1 誕生之前直到es5 時期,很多庫都建立了一些工具,讓 js 顯得貌似能支援類。儘管一些 js 開發者強烈認為這門語言不需要類,但為處理類而建立的**庫如此之多,導致 es6 最終引入了類。
es5 中的仿類結構
js 在 es5 及更早版本中都不存在類。與類最接近的是:建立乙個構造器,然後將方法指派到
該構造器的原型上。這種方式通常被稱為建立乙個自定義型別。例如:
function persontype(name) {
this.name = name;
persontype.prototype.sayname = function() {
console.log(this.name);
let person = new persontype("nicholas");
person.sayname(); // 輸出 "nicholas"
console.log(person instanceof persontype); // true
console.log(person instanceof object); // true
此**中的 persontype 是乙個構造器函式,並建立了單個屬性 name 。 sayname() 方法被
指派到原型上,因此在 persontype 物件的所有例項上都共享了此方法。接下來,使用 new
運算子建立了 persontype 的乙個新例項 person ,此物件會被認為是乙個通過原型繼承了
persontype 與 object 的例項。
這種基本模式在許多對類進行模擬的 js 庫中都存在,而這也是 es6 類的出發點。
es6基本的類的宣告
類宣告以 class 關鍵字開始,其後是類的名稱;剩餘部分的語法看起來就像物件字面量中的
方法簡寫,並且在方法之間不需要使用逗號。作為範例,此處有個簡單的類宣告:
class personclass {
// 等價於 persontype 構造器
constructor(name) {
this.name = name;
// 等價於 persontype.prototype.sayname
sayname() {
console.log(this.name);
let person = new personclass("nicholas");
person.sayname(); // 輸出 "nicholas"
console.log(person instanceof personclass); // true
console.log(person instanceof object); // true
console.log(typeof personclass); // "function"
console.log(typeof personclass.prototype.sayname); // "function"
es6中類關鍵字class本質是一種語法糖,而使用類實現的繼承其本質上就是原型的繼承.
為何要使用類的語法
類宣告不會被提公升,這與函式定義不同。類宣告的行為與 let 相似,因此在程式的執行到達宣告處之前,類會存在於暫時性死區內。
類宣告中的所有**會自動執行在嚴格模式下,並且也無法退出嚴格模式。
呼叫類構造器時不使用 new ,會丟擲錯誤。
試圖在類的方法內部重寫類名,會丟擲錯誤。
作為一級公民的類
在程式設計中,能被當作值來使用的就稱為一級公民( first-class citizen ),意味著它能作為參
數傳給函式、能作為函式返回值、能用來給變數賦值。 js的函式就是一級公民(它們有時又
被稱為一級函式),此特性讓 js 獨一無二
es6 延續了傳統,讓類同樣成為一級公民。這就使得類可以被多種方式所使用。例如,它能
作為引數傳入函式:
function createobject(classdef) {
return new classdef();
let obj = createobject(class {
sayhi() {
console.log("hi!");
obj.sayhi(); // "hi!
使用派生類進行繼承
es6 之前,實現自定義型別的繼承是個繁瑣的過程。嚴格的繼承要求有多個步驟。例如,研
究以下範例:
function rectangle(length, width) {
this.length = length;
this.width = width;
rectangle.prototype.getarea = function() {
return this.length * this.width;
function square(length) {
rectangle.call(this, length, length);
square.prototype = object.create(rectangle.prototype, {
constructor: {
value:square,
enumerable: true,
writable: true,
configurable: true
var square = new square(3);
console.log(square.getarea()); // 9
console.log(square instanceof square); // true
console.log(square instanceof rectangle); // true
square 繼承了 rectangle ,為此它必須使用 rectangle.prototype 所建立的乙個新物件來
重寫 square.prototype ,並且還要呼叫 rectangle.call() 方法。這些步驟常常會搞暈 js
的新手,並會成為有經驗開發者出錯的根源之一。
類讓繼承工作變得更輕易,使用熟悉的 extends 關鍵字來指定當前類所需要繼承的函式,即
可。生成的類的原型會被自動調整,而你還能呼叫 super() 方法來訪問基類的構造器。此處
是與上個例子等價的 es6 **:
class rectangle {
constructor(length, width) {
this.length = length;
this.width = width;
getarea() {
return this.length * this.width;
class square extends rectangle {
constructor(length) {
// 與 rectangle.call(this, length, length) 相同
super(length, length);
var square = new square(3);
console.log(square.getarea()); // 9
console.log(square instanceof square); // true
console.log(square instanceof rectangle); // true
使用 super() 時需牢記以下幾點:
你只能在派生類中使用 super() 。若嘗試在非派生的類(即:沒有使用 extends關鍵字的類)或函式中使用它,就會丟擲錯誤。
在構造器中,你必須在訪問 this 之前呼叫 super() 。由於 super() 負責初始化this ,因此試圖先訪問 this 自然就會造成錯誤。
唯一能避免呼叫 super() 的辦法,是從類構造器中返回乙個物件。
總結es6 的類讓 js 中的繼承變得更簡單,因此對於你已從其他語言學習到的類知識,你無須將其
丟棄。 es6 的類起初是作為 es5 傳統繼承模型的語法糖,但新增了許多特性來減少錯誤。
ES6 ES6標準let和const語句
es6 新增了let命令,用來宣告變數。它的用法類似於var,但是所宣告的變數,只在let命令所在的 塊內有效。a referenceerror a is not defined.b 1 上面 在 塊之中,分別用let和var宣告了兩個變數。然後在 塊之外呼叫這兩個變數,結果let宣告的變數報錯,v...
ES6 ES6學習三 變數的解構賦值
es6 允許按照一定模式,從陣列和物件中提取值,對變數進行賦值,這被稱為解構 destructuring 下面介紹的是陣列 物件 字串 數值和布林值 函式引數的解構賦值。1 模式匹配 只要等號兩邊的模式相同,左邊的變數就會被賦予對應的值。以前 let a 1 let b 2 let c 3 es6 ...
ES6系列 ES6簡介
2015年6月17日,ecmascript的第六個版本正式發布,該版本正式名稱為ecmascript 2015,但通常被稱為ecmascript 6或者es6。瀏覽器對es6的支援情況 es6主要應用於node.js,如果想用在瀏覽器中,就需要使用轉碼器 將es6 轉成es5 這意味著,可以用es6...