類定義 ES6完整學習阮老師的ECMAScript6入門。 技術一般水平有限,有什麼錯的地方,望大家指正。 以前我們使用ES5標准定義一個構造函數的過程如下: 通常首字母大寫的函數我們稱為構造函數(並不是一種語法約束,只是一種約定俗成的規律),屬性寫在方法裡面,函數寫在原型上面,這樣實例化(new操 ...
類定義
ES6完整學習阮老師的ECMAScript6入門。
技術一般水平有限,有什麼錯的地方,望大家指正。
以前我們使用ES5標准定義一個構造函數的過程如下:
function Person(name,age){ this.name = name; this.age = age; } Person.prototype.say = function(){ console.log("你好,我是"+this.name) } Person.prototype.show = function(){ console.log("年齡"+this.age+"一名小學生!"); }
通常首字母大寫的函數我們稱為構造函數(並不是一種語法約束,只是一種約定俗成的規律),屬性寫在方法裡面,函數寫在原型上面,這樣實例化(new操作)出來的對象既有屬性也有方法。
ES6為了更明朗構造函數這個概念了多了一個class語法,它會幫我們完成上面的一系列操作,我們可以把它看做是構造函數的變身,通常我們稱為類。JS中的類同函數一樣也有兩種聲明方式:
類聲明:
class Person{
}
類表達式:
var Person = class { }
現在我們利用類來對開始的構造函數進行變形:
class Person{ constructor(name,age){ this.name = name; this.age = age; } say(){ console.log("你好,我是"+this.name); } show(){ console.log("年齡"+this.age+"一名小學生!"); } }
我們實例化一個Person的對象,是可以正常使用的:
var me = new Person("zt",23); me.say(); me.show();
原來的構造函數現在變成了一個類,constructor就是構造函數對參數進行初始化的變形,say和show就是構造函數原型上面的函數。
類就是對有同樣特征的事物的一個統稱,在JS的類裡面只能包括函數,不能包含別的,如果我們需要給類添加一個屬性只能通過get/set存取器方法來實現:
class Person{ constructor(name,age){ this.name = name; this.age = age; } get message() { return "name:"+this.name+",age:"+this.age } } var me = new Person("zt",23); console.log(me.message);
constructor函數在類裡面最多只能有一個,它的主要職能就是初始化屬性,在執行new操作時先經由constructor函數將參數設置為對象的屬性,如果不需要存在初始化屬性那麼constructor可以省略。
函數修飾
類裡面定義的函數可以被修飾符修飾最常見的就是static。
class Person{ constructor(name,age){ this.name = name; this.age = age; } static say(){ console.log("由類調用"); } } Person.say();
一旦一個函數被static修飾,那麼這個函數就屬於類了,可以直接由類名來調用Person.say()。而普通函數是不能直接由類進行調用的,普通函數只能由實例化的對象來調用,被static修飾的函數是不能被實例化的對象調用的只能通過類直接來進行調用,這種函數等價於我們以前直接利用Person.fn = function(){}定義工具函數一樣。
類繼承
一個類可以繼承一個類,被繼承的類我們一般稱為父類,另一個稱為子類,通過extends來實現:
class Person{ constructor(name,age){ this.name = name; this.age = age; } static say(){ console.log("我是"+this.name); } } class Student extends Person{ }
新創建的Student類是子類,Person類是父類,子類會擁有父類裡面的所有函數(constructor和其他函數),子類繼承來的函數都是可以直接使用的:
var stu = new Student("zt",23) stu.say();
子類裡面沒有聲明任何函數,仍然可以調用say,say就是通過繼承得來的。
子類可以定義自己的特有的函數,如果和父類函數同名那麼就父類的函數就不會生效而是使用子類自身的函數(就是ES5原型鏈查找的套路):
class Person{ constructor(name,age){ this.name = name; this.age = age; } say(){ console.log("我是"+this.name); } } class Student extends Person{ say(){ console.log("我是子類的say函數!") } fn(){ console.log("我是子類函數fn") } } var stu = new Student("asaszt",23) stu.say();//我是子類的say函數! stu.fn();//我是子類函數fn
在子類中使用super
子類會繼承父類的constructor函數來初始化自身的屬性,同樣也可以添加自身特有的屬性,但是必須使用super來完成這個操作:
class Person{ constructor(name,age){ this.name = name; this.age = age; } } class Student extends Person{ constructor(name,age,sex){ super(name,age); this.sex = sex; } } var stu = new Student("zt",23,"男") console.log(stu.sex);//男
在子類中使用constructor來初始化屬性,首先使用super來對可繼承的屬性進行初始化,然後在通過this添加自身特有的屬性,this只有在調用super()之後才會存在。
super同樣可以調用父類的非靜態函數(此時我們可以把super看做是一個父類實例化出來的一個對象):
class Person{ constructor(name,age){ this.name = name; this.age = age; } say(){ console.log("我是父類的say函數"); } } class Student extends Person{ constructor(name,age,sex){ super(name,age); this.sex = sex; } say(){ super.say(); console.log("我是子類的say函數"); } } var stu = new Student("zt",23) stu.say();//我是父類的say函數 我是子類的say函數