在學習了C#以後,回頭再看JavaScript時,第一時間就想到關於Class和僞類,當初在看《JavaScript高程》和《JavaScript語言精粹》時,在關於原型和繼承的相關章節,不止一次的提到了僞類,並闡述了使用的僞類的優勢和缺點。「僞類」形式能夠給習慣了使用基於類的語言編程的後端程序員提供方便書寫JavaScript的便利,可是隱藏了語言的本質,而做爲一個從前端入門的程序員,對於類的概念始終模糊不清,即便當ES6推出了Class語法機制,也由於項目的關係和薄弱的基礎不敢貿然使用,只是淺嘗輒止於瞭解基本語法。前端
僞類是仿照基於類的語言,經過構造器函數產生對象。在C#中,類是程序的基本單元,經過定義類,類的構造函數,類的方法等,經過父類和子類的繼承關係,實現不少複雜的應用。而在JavaScript中,若是定義一個「類」呢?程序員
// 定義一個函數
function MathHandle(x, y) {
this.x = x
this.y = y
}
// 經過函數的prototype添加該函數的原型方法add
MathHandle.prototype.add = function () {
return this.x + this.y
}
var m = new MathHandle(1,2)
m.add() // 3
複製代碼
顯而易見,經過定義一個「僞類」MathHandle,添加prototype的原型方法,經過new關鍵字構造一個實例。而在C#中如何表現呢?es6
// 定義類
public class Mathhandle
{
private int x;
private int y;
// 定義類的構造函數
public MathHandle(int x, int y)
{
this.x = x;
this.y = y;
}
// 定義類的方法
public int add()
{
return x + y;
}
}
MathHandle m = new MathHandle(1, 2);
int sum = m.add() // 3
複製代碼
看了C#的語法再看JavaScript,會發現基於類的語言結構清晰,也更加嚴謹,所幸在ES6中推出了Class語法機制。編程
// 經過class關鍵字定義MathHandle類
class MathHandle {
// 類中的構造函數,也叫構造器
constructor(x, y) {
this.x = x
this.y = y
}
// 類中的構造方法
add() {
return this.x + this.y
}
}
const m = new MathHandle(1, 2) //建立Class的實例,並調用默認構造函數
m.add() // 3
複製代碼
看明白了C#的語法再看es6中的class就會很輕鬆,但是看了不少文章,對於在JavaScript中使用class不少人持謹慎的態度,class只是JavaScript的語法糖而已,並無改變語言的實質。後端
function MathHandle(x, y) {
// ...
}
typeof MathHandle // 'function'
MathHandle.prototype.consturctor === MathHandle // true
m.__proto__ === MathHandle.prototype // true
複製代碼
在第一種方法中,MathHandle的typeof返回的是‘function',這沒有問題,查看他的原型鏈能夠發現,他的隱式原型也等於函數自己,再來看看在class方法中是什麼樣子bash
class MathHandle {
// ...
}
typeof MathHandle // 'function'
MathHandle.prototype.consturctor === MathHandle // true
m.__proto__ === MathHandle.prototype // true
複製代碼
看來,在es6的class中,class定義的所謂的「類」的類型,依然是function,而實例的方法,也是經過原型傳遞的。弄懂了es6中class的本質,會發現類和繼承並無什麼神祕的地方。函數