記錄class的學習筆記,在回答別人的問題時發現本身的的理解偏差很大javascript
在沒有es6帶來的class的時候,咱們編寫JavaScript的時候不少時候會經過構造函數和原型鏈來添加方法屬性,實現class的功能。java
// Box是一個構造器 function Box(color) { this.type = 'circle'; this.color = color; } // 咱們能夠經過prototype的方式來加一條實例方法 Person.prototype.hello = function() { console.log('hello ' + this.color); } // 對於私有屬性(Static method),咱們固然不能放在原型鏈上了。咱們能夠直接放在構造函數上面 Person.fn = function() { console.log('static'); }; //經過new來建立 var circle = new Box('red');
可是在es6的規範中,可使用class語法,ES6 的class能夠看做只是一個語法糖,它的絕大部分功能,ES5 均可以作到,新的class寫法只是讓對象原型的寫法更加清晰、更像面向對象編程的語法而已。上面的代碼用 ES6 的class改寫,就是下面這樣。es6
class Box { constructor(color) { this.color = color; this.type="corcle" } hello() { console.log('hello ' + this.name); } static fn() { console.log('static'); }; }
上面代碼定義了一個「類」,能夠看到裏面有一個constructor方法,這就是構造方法,而this關鍵字則表明實例對象。編程
須要注意:
1.class內的方法不須要function
關鍵字,直接把函數定義放進去了就能夠了。
2.另外,方法之間不須要逗號分隔,加了會報錯。
3.class內部默認是嚴格模式,
須要注意這個和JavaScript
中的對象寫法是不同的。而是當作是構造函數的寫法。並且目前使用typeof
來判斷class
的類型的時候返回的結果是function
。函數
constructor方法是類的默認方法,經過new命令生成對象實例時,自動調用該方法。一個類必須有constructor方法,若是沒有顯式定義,一個空的constructor方法會被默認添加。學習
class Box { } // 等同於 class Box { constructor() {} }
就像使用構造函數同樣使用new
命令來建立一個實例。若是忘記加上new
,像函數那樣調用Class
,將會報錯。this
class Box{...} var circle = new Box();
class的實例對象就和普通的對象相似,都是能夠看過是經過new
一個構造函數生成的,prototype
這裏有幾個問題須要注意:code
class
表達式就像函數表達式同樣,能夠把class
來賦值給變量,class
不存在變量提高,內部默認嚴格模式
暫時沒有標準的支持私有方法和私有屬性this
的指向是class
實例對象,須要注意若是在外單獨調用方法時須要當心this
的指向Generator
函數前面添加*
便可對象
類至關於實例的原型,全部在類中定義的方法,都會被實例繼承。若是在一個方法前,加上static關鍵字,就表示該方法不會被實例繼承,而是直接經過類來調用,這就稱爲「靜態方法」。
注意,若是靜態方法包含this關鍵字,這個this指的是類,而不是實例。
ES6 明確規定,Class 內部只有靜態方法,沒有靜態屬性。因此應該這樣書寫一個靜態屬性:
class Foo { } Foo.prop = 1; Foo.prop // 1
下面是錯誤的觸類旁通:
// 如下兩種寫法目前都無效 class Foo { // 寫法一 prop: 2 // 寫法二 static prop: 2 } Foo.prop // undefined
不過目前已經有了新的提案來支持類的靜態屬性和實例屬性,
類的實例屬性能夠用等式,寫入類的定義之中。
class MyClass { myProp = 42; constructor() { console.log(this.myProp); // 42 } }
類的靜態屬性只要在上面的實例屬性寫法前面,加上static關鍵字就能夠了。
class MyClass { static myStaticProp = 42; constructor() { console.log(MyClass.myStaticProp); // 42 } }