在其餘的衆多編程語言中(例如Python),都有class(類)這個概念,而JS在ES6規範中終於補上了編程
類是具備一些相同特徵的對象,例如車都有顏色、輪子、座椅等元素,還有行駛時速,只不過不一樣的車,這些特徵的值是不同的編程語言
實際上class的本質,一方面是面向對象的思想,另外一方面則是封裝函數
聲明class時,咱們直接用class關鍵字+類名,在其中添加構造函數constructor來給後續實例化的對象添加屬性/方法,這裏的this就指向實例化被生成的對象this
這裏的構造函數必須命名成constructor,用來接收實例化時傳入的參數(也就是new 類名後的參數),可是具體如何處理還得看構造函數內部的書寫對象
類比於對象中的方法,也能夠給類添加方法,例如圖例中的speedUp,相比於constructor是獨立存在的blog
其實某種程度上說,class有點像工廠模式聲明對象繼承
靜態方法/屬性是在類裏聲明的,只屬於類本身的,不可被類實例擁有,只是類本身擁有內存
靜態方法聲明時用static關鍵字,寫在類的內部,而靜態屬性則用類名.屬性名=屬性值的方法聲明,能夠寫在類的內部/外部開發
此外,類裏的方法和靜態方法若是同名,不會引發衝突get
能夠用靜態屬性來檢測這個類的實例的數量,原理就是每次建立一個新的類,都是在調用類裏的constructor方法,裏面的代碼都會被執行
這裏因爲Car.num這個屬性是一個全局變量,所以不會被回收,但注意要在聲明對象前掛上靜態屬性,不然沒法修改靜態屬性
相比於直接在類上添加屬性(動態,依靠外界傳入),能夠在類上綁定一個靜態屬性,這個屬性的屬性值能夠經過訪問類來找到
好處在於:讓屬性和類關聯,避免污染全局
這裏主要是提供一個類的方法,不用實例化生成對象就可直接調用的方法
能夠模仿函數表達式,把一個類賦值給一個常量/變量(主要看聲明)
注意聲明時,類名能夠在類中訪問,但不可在類外面訪問(這一點也相似於函數的表達式聲明)
類表達式還能夠自執行(相似於函數的特性),但實際開發中基本不用
相似於在屬性中提供一個鉤子,能夠在獲取/設置屬性值時候作一些額外的事情,這些事情在設置/訪問以前執行
實際上在ES5中,get/set方法就有了,能夠添加在對象中,用get/set聲明+屬性名+(){}的方法聲明(也能夠理解成聲明一個與屬性名同名的函數),表示在訪問/修改屬性的時候會執行的操做
注意set中必須傳入一個參數,即爲設置的屬性值,不然報錯
若是執行的操做有和獲取/修改屬性相關的,則可能引起棧內存溢出
也能夠用Object的defineProperty方法來設置,直接在第三個參數裏寫上get和set的兩個函數,至關於給對象添加兩個方法
不一樣於方法中的set,這裏set函數中不必定要加形參
須要注意如下問題:
1.用defineProperty方法添加的屬性不可用for-in語句遍歷到的,須要給其添加enumerable屬性(true),可是該屬性一旦設置不可修改,不然報錯
(補充案例)
2.若是一個屬性有get和set方法,必須用defineProperty方法設置其爲writable,不然屬性是沒法被修改的
(案例)
此外,訪問/設置屬性時,先調用get/set方法,再調用輸出(console.log)等方法
(補充個案例說明問題)
(關於set和get實在是太多地方不理解……)
用來獲取類的名稱
若是是類表達式聲明,有類名稱則返回類名稱,不然返回賦值的變量名稱
返回的是new聲明後的類/函數
該屬性不可直接調用,須要放在類/函數裏
ES6的類也能夠繼承,其中被繼承的類叫父類(基類),繼承的類爲子類
相似於對象的繼承,類的繼承也可讓子類獲取父類的方法和屬性,從而實現子類屬性/方法的添加
ES6的類中,可以使用extends來繼承父類的屬性,並在constructor裏給子類的屬性賦值前,使用super方法來調用父類的構造函數,以實現繼承
上面的例子中能夠看出,super能夠在子類的構造函數中使用,以調用父類構造函數
此外還能夠做爲對象的方式調用,可是在靜態方法/非靜態方法裏使用時,訪問到的分別是父類的原型/對象
此外,在調用super時,父類的this始終是子類的this