1. 程式人生 > 實用技巧 >ES6語法:class類,從瞭解到使用

ES6語法:class類,從瞭解到使用

前情提要

  JavaScript 語言中,在使用類之前,生成例項物件的傳統方法是通過使用建構函式。

一、建構函式:

   定義:通過 new 函式名 來例項化物件的函式叫建構函式。

  主要功能:為初始化物件,特點是和new 一起使用。new就是在建立物件,從無到有,建構函式就是在為初始化的物件新增屬性和方法。

   注意:任何的函式都可以作為建構函式存在建構函式定義時首字母大寫(規範)。

   對new的理解:new 申請記憶體, 建立物件,當呼叫new時,後臺會隱式執行new Object()建立物件。所以,通過new建立的字串、數字是引用型別,而是非值型別。

  1、常用的建構函式:

    • var arr = [];為 var arr = new Array()的語法糖

    • var obj = {}; 為 var obj = new Object()的語法糖

    • var date = new date()

    • 當然還有很多,這裡就不一 一列舉了。

  2、執行一個建構函式:

function A(name,age){   this.name = name;   this.age = age; }
A.prototype.info = function(){
  return "姓名"+ "" + this.name + "年齡" + this.age
}
let a = new A("張三",22)//例項化a
//列印 a結果
A{
  name:"張三",
  age:22
}
//列印 a.info() 結果為 "姓名張三年齡22"

二、class 類

   由來:因為上面建構函式的寫法跟傳統的面嚮物件語言差異很大,給很多程式設計師造成很多困惑,所以ES6 提供了更接近傳統語言的寫法,引入了 Class(類)這個概念,作為物件的模板。

   通過class關鍵字,可以定義類。

   1、class類基本語法的使用

class A{
  constructor(){
    //成員屬性

    this.name = name
    this.age = age
  }
  //靜態方法 如果在一個方法前,加上static關鍵字,就表示該方法不會被例項繼承,而是直接通過類來呼叫,這就稱為“靜態方法”。A.nihao()
  static nihao(){
    console.log("你好")
  }
  //成員方法


  info(){
    return "姓名"+ "" + this.name + "年齡" + this.age
  }
}

    與上面的建構函式相比之言,新的class寫法讓物件原型的寫法更加清晰、更像面向物件程式設計的語法。

    注意:定義info()方法的時候,前面不需要加上function這個關鍵字,直接把函式定義放進去了就可以了方法與方法之間不需要逗號分隔,加了會報錯。

    新增靜態屬性:

   靜態屬性指的是 Class 本身的屬性,即Class.propName,而不是定義在例項物件(this)上的屬性。

    老式寫法:

    class A{}

    A.props=1 //A.props= 1 props就是A的靜態屬性

    新式寫法:

    class A{

     static props = 1

    }

    新寫法是顯式宣告(declarative),而不是賦值處理,語義更好。

    私有方法私有屬性

      私有方法兩種寫法:    

      function bar(name){

       return this.name = name

      }

      class A{

        foo(name){

          bar.call(this,name)

        }

      }

     這樣寫的原因是類內部的所有方法都是對外可見的。foo是公開方法,內部呼叫了bar.call(this, baz)。這使得bar()實際上成為了當前類的私有方法。

     還有一種方法是利用Symbol值的唯一性,將私有方法的名字命名為一個Symbol值。

     const bar = Symbol('bar')

     const name = Symbol('name')

     class A{

      //公有方法

      foo(){

        this[bra](name)

      }

      //私有方法

      [bar](name){

       return this[name] = name

      }

     }

    私有屬性

    第一種方法是在屬性名之前,使用#表示。

    class A{

      #count = 0

    }

    注意:#count就是私有屬性,只能在類的內部使用(this.#count)。如果在類的外部使用,就會報錯。

    這種寫法不僅可以寫私有屬性,還可以用來寫私有方法。

    私有屬性也可以設定 getter 和 setter 方法。

class Foo { #a; #b;
#xVal = 0; constructor(a, b) { this.#a = a; this.#b = b; } #sum() { return this.#a + this.#b; } printSum() { console.log(this.#sum()); }

get #x() { return #xValue; }

set #x(value) {

this.#xValue = value;

}

}
私有屬性不限於從this引用,只要是在類的內部,例項也可以引用私有屬性。
私有屬性和私有方法前面,也可以加上static關鍵字,表示這是一個靜態的私有屬性或私有方法。

  2、深入介紹class類和class繼承

   <1>

    ES6 的類,完全可以看作建構函式的另一種寫法。

class A{}typeof A //function A === A.prototype.constructor // ture 可以看出,類的資料型別就是函式,類本身就指向建構函式。

    使用的時候,也是直接對類使用new命令,跟建構函式的用法完全一致。

    <2>

    class A{

      constructor(){}

      info(){}

      toString(){}

      toVal(){}

    }

    等同於

    A.prototype={

      info(){},

      toString(){},

      toVal(){},

    };

    建構函式的prototype屬性,在類裡面也存在,類的所有方法都定義在類的prototype屬性上面.

    因此,在類的例項上面呼叫方法,其實就是呼叫原型上的方法。

    <3>

    Object.assign()方法可以很方便地一次向類新增多個方法。如下:

    Object.assign(A.prototype,{

      toString(){},

      toVal(){},

     })

    <4>

    類的內部所有定義的方法,都是不可列舉的,如下:

class A{ constructor(x, y) { // ... } toString() { // ... } } Object.keys(A.prototype) // []
<5>

    類內部可以忽略不寫constructor,因為JavaScript 引擎會自動為它新增一個空的constructor()方法。如下:

    class A{} === class A{constructor(){}} //true

    <6>

    constructor()方法預設返回例項物件(即this),完全可以指定返回另外一個物件。

    <7>

    類必須使用new呼叫,否則會報錯。這是它跟普通建構函式的一個主要區別,後者不用new也可以執行。

三、class繼承:

<1>class 通過extends關鍵字實現繼承,這樣的繼承方式非常清晰和方便

class A{}

class B extends A{

 constructor(){

   super() //關鍵字,super作為函式呼叫時,代表父類的建構函式

}

} //B類繼承了A類的所有屬性和方法

<2>Object.getPrototypeof(B)=== A //true 方法可以用來從子類上獲取父類 ,因此,可以使用這個方法判斷,一個類是否繼承了另一個類。