簡單學ES6 - class

 

前言html

隨着ES6標準的定稿,衆多的特性也趨於穩定,各大瀏覽器也在逐步實現這些特性,那麼對ES6有更多的瞭解就無可厚非了。node

準備

在學習ES6以前,咱們須要有一個環境來測試ES6代碼。在這裏我推薦使用node的分支io.js。git

  1. 如何安裝?es6

    1. 下載地址:https://iojs.org/en/index.html,若是各位小夥伴不習慣英文,能夠把url中的en修改成cn。
    2. 而後根據本身的操做系統版本,下載合適的安裝包(主要指Windows系統)進行安裝。
    3. 安裝過程就不一一贅述了,和通常軟件同樣。
  2. 如何驗證安裝成功?github

    1. 打開cmd,而後輸入iojs -v,若是輸出一個版本號,那麼就表明io.js安裝成功。(PS:我如今使用的是v1.2.0)
    2. 也能夠輸入iojs -p process.versions.v8查看iojs所使用的V8(PS:不是V8發動機)的版本。(PS:我這兒顯示4.1.0.14)

小窺ES6

在測試ES6代碼前,咱們能夠先看下io.js對ES6的支持:https://iojs.org/cn/es6.htmlweb

接下來,開始咱們的ES6-Class之旅:canvas

一、class 基礎

你們應該知道,在大部分面向對象的語言中,都有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便可。

其餘

  1. 若是想一覽全部的ES6新特性,能夠參考https://github.com/lukehoban/es6features
  2. 若是想系統的學習ES6,那麼推薦http://es6.ruanyifeng.com/
  3. 想了解更多Classes in ECMAScript 6,可參考http://www.2ality.com/2015/02/es6-classes-final.html
相關文章
相關標籤/搜索