ES6中的class
簡(jiǎn)介
JS語(yǔ)法中起始是原生不怎么支持面向?qū)ο蟮模械拿嫦驅(qū)ο笃鹪淳ㄟ^(guò)一個(gè)構(gòu)造函數(shù),這一點(diǎn)和JAVA等語(yǔ)言原生支持面向?qū)ο蟮恼Z(yǔ)言有很大的不同。
通常生成一個(gè)對(duì)象的傳統(tǒng)方式就是通過(guò)構(gòu)造函數(shù),這也是JS唯一面向的對(duì)象唯一起點(diǎn)。
function Point(x, y){
this.x = x;
this.y = y;
}
Point.prototype.toString = function(){
return '(' + this.x + ', ' + this.y + ')';
};
var p = new Point(1,3);
注意 這時(shí)ES5的原生寫法, 在接下來(lái)的篇幅我們會(huì)詳細(xì)接受ES6中 關(guān)鍵字CLASS的使用方法。
在ES6中使用class和 es6其實(shí)再本質(zhì)上沒(méi)有任何的區(qū)別,都是通過(guò)構(gòu)造函數(shù)來(lái)做文章,只不過(guò)class的使用更符合類似向我這種通過(guò)JAVA轉(zhuǎn)過(guò)來(lái)的使用習(xí)慣。
class Point{
constructor(x, y){
this.x = x;
this.y = y;
}
toString(){
return '(' + this.x + ', ' + this.y + ')';
}
}
基本上來(lái)講 class已經(jīng)是構(gòu)造函數(shù)的另外一種寫法,有幾點(diǎn)不同之處在于
- class中的函數(shù) 基本不用逗號(hào)來(lái)區(qū)別
- Constructor toString 等方法都不需要加上function 直接起一個(gè)函數(shù)名并 定義其中方法即可
class Point{
}
typeof Point // function
Point === Point.prototype.constructor // true
在構(gòu)造函數(shù)的prototype屬性,在ES6的類上面繼續(xù)存在,實(shí)際上所有定義再類的方法都是定義再類的prototype熟悉上面。
調(diào)用類的實(shí)例上面的方法其實(shí)就是調(diào)用原型的方法。
除非是顯式的指名了this對(duì)象的屬性,否則所有都是類的prototype上面
ES6與ES5不同之處在于 所有定義在class的方法都是不可枚舉的,但是所有ES5 prototype上的方法都是可枚舉的。
2. 嚴(yán)格模式
類和模塊的內(nèi)部,默認(rèn)都是嚴(yán)格模式,所以不需要 use strict來(lái)指定運(yùn)行模式。起始ES6已經(jīng)慢慢的將整個(gè)語(yǔ)言提升為嚴(yán)格模式了
3. 類的實(shí)例對(duì)象
與ES5一樣,實(shí)例的屬性除非顯示定義再其本身(this對(duì)象上),否則都是定義在原型上。
class Point{
constructor(x, y){
this.x = x;
this.y = y;
}
toString(){
return '(' + this.x + ',' + this.y + ')';
}
}
var point = new Point(2, 3);
point.toString(); /// (2, 3);
point.hasOwnProperty('x'); // true
point.hasOwnProperty('y'); // true
point.hasOwnProperty('toString'); // false 定義再Point的原型對(duì)象上
point.__proto__.hasOwnProperty('toString'); // true 對(duì)象的原型對(duì)象 __proto__
所有的類的實(shí)例共享一個(gè)原型對(duì)象 這意味可以通過(guò)實(shí)例的 proto 屬性添加方法
4. 私有方法與私有屬性
私有方法
在原生的ES6的語(yǔ)法中沒(méi)有支持私有方法的,所以我們只能繞開的來(lái)是使用 _開頭的方法名來(lái)表示這個(gè)方法是私有方法
class Demo{
_printPrivate(name)
}
私有屬性
5. this的指向
js最讓人頭疼的便是this的指向, 在類的方法內(nèi)部如果含有this,它默認(rèn)指向類的實(shí)例。但是,一旦單獨(dú)來(lái)使用該方法,this很可能會(huì)改變
class Logger{
printName(name = 'there'){
this.print(`Hello ${name}`);// 1. 默認(rèn)this指向的是Logger的實(shí)例
}
print(text){
console.log(text);
}
}
const logger = new Logger();
const {printName} = logger();
printName();// 2. 因?yàn)樵谡{(diào)用函數(shù) 導(dǎo)致this 丟失了
因?yàn)檎Z(yǔ)言設(shè)計(jì)的緣故導(dǎo)致this會(huì)指向該方法運(yùn)行的所在的環(huán)境,
解決方案一般有兩種:
- 講方法綁定 再構(gòu)造方法中綁定this ,這樣就不會(huì)找不到print方法
- 第二種解決方法是使用箭頭函數(shù)
6. Class的getter setter方法
通過(guò)使用類 可以使用get和set關(guān)鍵字,對(duì)某個(gè)屬性設(shè)置存值函數(shù)和取值函數(shù),攔截該屬性的存取行為
7. Class的靜態(tài)方法
- 類的靜態(tài)方法只能通過(guò)類來(lái)調(diào)用
- 父類的靜態(tài)方法,可以被子類繼承