前言html
隨着ES6標準的定稿,衆多的特性也趨於穩定,各大瀏覽器也在逐步實現這些特性,那麼對ES6有更多的瞭解就無可厚非了。node
在學習ES6以前,咱們須要有一個環境來測試ES6代碼。在這裏我推薦使用node的分支io.js。git
如何安裝?es6
如何驗證安裝成功?github
iojs -v
,若是輸出一個版本號,那麼就表明io.js安裝成功。(PS:我如今使用的是v1.2.0)iojs -p process.versions.v8
查看iojs所使用的V8(PS:不是V8發動機)的版本。(PS:我這兒顯示4.1.0.14)在測試ES6代碼前,咱們能夠先看下io.js對ES6的支持:https://iojs.org/cn/es6.html。web
接下來,開始咱們的ES6-Class之旅:canvas
你們應該知道,在大部分面向對象的語言中,都有class的說法,那麼在早期的Js中,面向對象的實現比較特殊,咱們必需要用function來模擬。如:瀏覽器
//ES5及如下 function Point(x, y){ this.x = x; this.y = y; } var p1 = new Point(100, 100);
然而在ES6中,咱們能夠直接使用class關鍵字,如:ruby
//ES6 'use strict' //不能去掉,要否則iojs會提示不認識class。 class Point{ constructor(x, y){ this.x = x; this.y = y; } } var p1 = new Point(100, 100); console.log(p1);
將以上代碼保存爲1.js,那麼執行以下命令:iojs --es_staging 1.js
就能夠看到"{x:100, y: 100}"這個結果了。(PS:注意要在1.js的目錄打開cmd)。markdown
接下來,看一個複雜點的,繼承:
//ES6 'use strict' class Point{ constructor(x, y){ this.x = x; this.y = y; } } var p1 = new Point(100, 100); console.log(p1); class ColorPoint extends Point{ constructor(x, y, color){ super(x, y); this.color = color; } } var cp = new ColorPoint(50, 50, 'red'); console.log(cp); //輸出繼承關係 console.log(cp instanceof ColorPoint); //true console.log(cp instanceof Point); //true
能夠看到,和大部分語言的繼承都很相似,若是你有其餘面嚮對象語言的基礎,那麼很容易就能理解。
對Point和ColorPoint進行typeof,結果很明顯也能看到是function。
console.log(typeof Point); // function console.log(typeof ColorPoint); // function
那若是對class進行函數調用呢?
Point(100, 100); //Error
如上,必須經過new調用class,直接使用函數調用則會報錯。
再來對比如下代碼:
//標準的函數能夠先寫調用語句,後寫申明語句。由於會定義前置 foo(); function foo(){} //若是是class呢? new Foo(); //Error,Foo is not defined class Foo{}
如上,若是是定義的class,那麼必需要定義語句在前,調用在後。
再來看如下的情形:
function funThatUseBar(){ new Bar(); } //funThatUseBar(); //Error,Bar is not defined class Bar{} funThatUseBar(); //ok
如上,若是先使用了Bar,那麼也是會報錯的。必需要優先定義class。
附上以上全部的js,會報錯的語句,進行了註釋。
//ES6 'use strict' class Point{ constructor(x, y){ this.x = x; this.y = y; } } var p1 = new Point(100, 100); console.log(p1); class ColorPoint extends Point{ constructor(x, y, color){ super(x, y); this.color = color; } } var cp = new ColorPoint(50, 50, 'red'); console.log(cp); //********************************************* //輸出繼承關係 console.log(cp instanceof ColorPoint); //true console.log(cp instanceof Point); //true console.log(typeof Point); // function console.log(typeof ColorPoint); // function //Point(100, 100); //Error //************************************ //標準的函數能夠先寫調用語句,後寫申明語句。由於會定義前置 foo(); function foo(){} //若是是class呢? //new Foo(); //Error,Foo is not defined class Foo{} //******************************************* function funThatUseBar(){ new Bar(); } //funThatUseBar(); //Error,Bar is not defined class Bar{} funThatUseBar(); //ok
ES6中、class的主體只能包含方法,不能包含數據屬性。若是在類中包含變量定義,則會報錯。class中的方法有三種類型:構造函數、靜態方法、原型方法,如:
class Class1{ //構造 constructor(options){ } // 靜態方法,靜態方法用static修飾 static staticMethod(){ return 'static method'; } prototypeMethod(){ return 'prototype method'; } }
其中,每一個class和class原型的constructor都是相等的,同時class本質也是function
console.log(Class1 === Class1.prototype.constructor) // true console.log(typeof Class1) // function
而後咱們對類中的方法作測試
var p = console.log; p(typeof Class1.prototype.prototypeMethod); Class1.prototype.prototypeMethod() // 原型方法調用方式 p(typeof Class1.staticMethod); Class1.staticMethod() //靜態方法調用方式
Getters 和 Setters 的用法
class Class2{ get name(){ return 'jay'; } set name(value){ console.log('set name = ' + value); } } var c2 = new Class2(); c2.name = 'hu'; // "set name = hu" console.log(c2.name); // "jay"
當使用了get和set時,那麼針對屬性的get和set會自動調用class中相關的方法。
貼出全部Js代碼:
'use strict' class Class1{ //構造 constructor(options){ } // 靜態方法 static staticMethod(){ return 'static method'; } prototypeMethod(){ return 'prototype method'; } } console.log(Class1 === Class1.prototype.constructor); console.log(typeof Class1); var p = console.log; p(typeof Class1.prototype.prototypeMethod); p(typeof Class1.staticMethod); class Class2{ get name(){ return 'jay'; } set name(value){ console.log('set name = ' + value); } } var c2 = new Class2(); c2.name = 'hu'; console.log(c2.name);
簡單的繼承關係,以下:
'use strict' class Class1{ toString(){ return 'parent class.'; } } class SubClass extends Class1{ toString(){ return 'sub class.'; } } var sc = new SubClass(); console.log(sc.toString()); // "sub class"
其中,sc是Class1的實例,也是SubClass的實例:
console.log(sc instanceof Class1); //true console.log(sc instanceof SubClass); //true
若是要調用父類的方法,怎麼辦呢?
class SubClass2 extends Class1{ toString(){ return super.toString(); } } var sc2 = new SubClass2(); console.log(sc2.toString());
在繼承關係中,子類的原型等於父類:
console.log(Object.getPrototypeOf(SubClass2) === Class1); //true
在子類中訪問父類構造,使用super便可。