JavaScript class 類

admin發表於2018-12-03

如果您是一位使用典型面嚮物件語言進行開發的程式設計人員。

那麼對於class類的應用必定非常熟悉,比如建立物件例項,繼承或者多型等等。

但當您學習JavaScript時候,可能會感覺非常不適應,它的繼承模型與典型面嚮物件語言截然不同。

首先看一段程式碼例項:

[JavaScript] 純文字檢視 複製程式碼
function Antzone(webName, address) {
  this.webName = webName;
  this.address = address;
}
Antzone.prototype.showInfo = function () {
  console.log(this.webName + "位於" + this.address);
}
var antzone = new Antzone("螞蟻部落", "青島市南區");
antzone.showInfo();

通過建構函式Antzone建立物件例項antzone,並且繼承原型物件上自定義的showInfo方法。

上面程式碼是ES2015之前建立物件例項並實現繼承的方式,函式充當class類的角色。

一.ES2015增加class類:

為了讓JavaScript看起來更加接近典型面嚮物件語言一些,ES2015新增class樣式類。

但是實質上只是一種語法糖,比如繼承還是利用原型鏈模式。

將前面的程式碼利用class類改寫如下:

[JavaScript] 純文字檢視 複製程式碼
class Antzone{
  constructor(webName,address){
    this.webName = webName;
    this.address = address;
  }
  showInfo(){
    console.log(`${this.webName}位於${this.address}`);
  }
}

let antzone=new Antzone("螞蟻部落", "青島市南區");
antzone.showInfo();

程式碼分析如下:

(1).通過class關鍵字建立一個類Antzone。

(2).constructor()是類的構造方法,當通過類建立物件時候,它會預設首先執行。

(3).this指向類的物件例項。

(4).showInfo是一個方法,它其實定義在prototype原型物件之上,後面會介紹。

特別說明:

(1).類中的方法不需要使用function宣告,否則會報錯。

(2).方法與方法之間不需要用逗號分隔,後面程式碼會有體現。

(3).類內部預設使用嚴格模式,不用刻意宣告。

二.類的實質還是函式:

JavaScript類是語法糖,它的實質還是函式,程式碼驗證如下:

[JavaScript] 純文字檢視 複製程式碼執行程式碼
class Antzone{
  // code
}
console.log(typeof Antzone)

程式碼執行效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201812/03/090459p1z7hf70i32r721f.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

列印結果為"function"足以證明這一結論,但是又有不同之處。

(1).類不具有提升現象:

函式具有宣告提升現象,但是從類不具有,必須先宣告後使用,驗證如下:

a:3:{s:3:\"pic\";s:43:\"portal/201812/03/090518jn4zz1jxaffa64j1.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

程式碼報錯,類Antzone必須先宣告再使用。

關於函式宣告提升現象可以參閱JavaScript 變數與函式宣告前置一章節。

(2).類必須使用new呼叫:

函式除了使用new 用作建構函式之外,也可以直接呼叫作為普通函式。

但是class類必須使用new呼叫,否則會報錯,不再做演示。

三.constructor構造方法:

任何一個類都具有一個建構函式,即便沒有顯式宣告。

預設建構函式返回類的例項物件,當然也可以人為改變,程式碼如下:

[JavaScript] 純文字檢視 複製程式碼執行程式碼
class Antzone {
  constructor() {
    return Object.create({});
  }
}
console.log(new Antzone() instanceof Antzone)

程式碼執行效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201812/03/090626s1oroote1yoiv5v9.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

四.方法與屬性的位置:

有些時候不要被一些假象所矇蔽,看如下程式碼例項:

[JavaScript] 純文字檢視 複製程式碼
class Antzone{
  constructor(webName,address){
    this.webName = webName;
    this.address = address;
  }
  showInfo(){
    console.log(`${this.webName}位於${this.address}`);
  }
  do(){
    console.log("JavaScript教程");
  }
}

上面程式碼,雖然showInfo與do方法宣告在類中,但是實質上它們位於原型鏈之上。

也就是說它倆並非物件例項的自有方法,而是繼承自原型鏈。

宣告在構造方法constructor中的,則是物件例項自有,程式碼驗證如下:

[JavaScript] 純文字檢視 複製程式碼執行程式碼
class Antzone{
  constructor(webName,address){
    this.webName = webName;
    this.address = address;
  }
  showInfo(){
    console.log(`${this.webName}位於${this.address}`);
  }
  do(){
    console.log("JavaScript教程");
  }
}
let antzone=new Antzone("螞蟻部落", "青島市南區");
console.log(antzone.hasOwnProperty("showInfo"));
console.log(antzone.hasOwnProperty("webName"));

程式碼執行效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201812/03/090728x8l9ljpb58bplobl.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

上面列印結果印證了上述結論,hasOwnProperty參閱JavaScript hasOwnProperty()一章節。

還有一個特點需要強調,類內部定義的方法都是不可列舉的,大家可以自行測試一下。

五.建立類的方式:

除了前面已經介紹的使用類宣告方式建立類,也可以使用表示式方式建立。

這一點與建立函式也比較類似,程式碼例項如下:

[JavaScript] 純文字檢視 複製程式碼
let Antzone = class innerName {
  constructor(webName) {
    this.webName = webName;
  }
  showInfo() {
    console.log(this.webName);
  }
}

上面通過表示式方式建立類Antozne。

innerName可以省略,它的作用不大,只能夠在類的內部使用,否則報錯。

六.name屬性:

此屬性返回類名,這一點與函式的name屬性完全一樣。

前面已經提到過,類本質就是函式,不難理解。

程式碼例項如下:

[JavaScript] 純文字檢視 複製程式碼執行程式碼
class Antzone {
}
console.log(Antzone.name)

程式碼執行效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201812/03/090854hpdwwznxqwxwcqnk.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

再來看錶達式方式建立的類,程式碼如下:

[JavaScript] 純文字檢視 複製程式碼執行程式碼
let Antzone = class innerName{
  // code
}
let Ant=class{
  // code 
}
console.log(Antzone.name);
console.log(Ant.name);

程式碼執行效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201812/03/090934p1wm47thmhd8rh31.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

優先返回class關鍵字後面的名字,如果沒有則返回儲存類的變數名稱。

七.關於類的其他知識:

關於class類知識還有很多,考慮到文章篇幅問題,其他知識放入以下對應文章。

(1).JavaScript extends 繼承一章節。

(2).JavaScript 例項屬性一章節。

(3).JavaScript static 靜態屬性和方法一章節。

(4).JavaScript super一章節。

(5).JavaScript new.target一章節。

相關文章