1.靜態方法
類相當於實例的原型,所有在類中定義的方法,都會被實例繼承。如果在一個方法前,加上static關鍵字,就表示該方法不會被實例繼承,而是直接通過類來嗲用,這就稱為靜態方法。
class P { static show() { console.log('這是類的靜態方法') } } const p1 = new P() P.show() // 這是類的靜態方法 p1.show() // p1.show is not a function
上面代碼中,P類有個靜態方法,可以直接通過P類調用該方法,但是如果通過P類的實例來調用該方法,則會拋出一個錯誤,表示不存在該方法。
且,如果靜態方法上包含this關鍵字,這個this指的是類,而不是實例。
class P { static show() { this.foo() } static foo() { console.log('hello') } foo() { console.log('world') } } P.show() // hello
上面代碼中,P類的靜態方法show調用了this.foo。這里的this值得是P類,而不是foo的實例,等同於調用了P.foo。另外還可以看出,靜態方法可以與非靜態方法重名。
父類的靜態方法是可以被子類繼承的:
class P { static show() { console.log('這是類的靜態方法') } } class Bar extends P {} Bar.show() // 這是類的靜態方法
靜態方法也是可以從super對象上調用的:
class P { static show() { console.log('這是P類的靜態方法') } } class Bar extends P { static show() { super.show() console.log('這時Bar類的靜態方法') } } Bar.show() // 這是類的靜態方法 // 這時Bar類的靜態方法
2.靜態屬性
靜態屬性指的是Class本身的屬性,而不是定義在實例對象上的屬性。
class Foo{ } Foo.prop = 1 Foo.prop // 1
上面的寫法為Foo類定義了一個靜態屬性prop。
目前,只有這種寫法可行,因為ES6明確規定,Class內部只有靜態方法,沒有靜態屬性。現在有一個提案提供了類的靜態屬性,寫法是在實例屬性的前面,加上static關鍵字。
class P { static myStaticProp = 12 constructor() { console.log(P.myStaticProp) } }
這個寫法大大方便了靜態屬性的表達
// 老寫法 class Foo { // ... } Foo.prop = 1; // 新寫法 class Foo { static prop = 1; }
3.私有方法和私有屬性
私有方法和私有屬性,是只能在類的內部訪問的方法和屬性,外部不能訪問。這是常見需求,有利於代碼的封裝,但是ES6不提供,只能通過變通方法實現
方法一:
在命名上加以區別。
class P { // 公有方法 foo(bar) { this._bar(baz) } // 私有方法 _bar(baz) { return (this.snaf = baz) } }
上面代碼中_baz方法前面的下划線,表示這是一個只限於內部使用的私有方法。但是這樣處理,在類的外部還是可以調用到這個方法。
方法二:
索性將私有方法移出類,因為類內部的所有方法都是對外可見的。
class P { foo(bar) { bar.call(this, bar) } } function bar(baz) { return (this.snaf = baz) }
上面代碼中,foo是公開方法,內部調用了bar.call(this,baz)。這使得bar()實際上成為了當前類的私有方法。