es6
真正的引入的面相對象的類
,以前我們總是通過其他手段來模擬類
這種形式,現在終於有了,我有點開心,又有點難過,因為在我看來,js
並不是所謂的面相對象的語言,反而更偏向函數式,原型繼承是他真正的面目。面相對象不過是人們在思考問題時總結出一套有效的、大家都認同的解決問題的思路。在其他語言、各種領域取得成功之后,又將這種思想帶入js
中,為的是將已有的經驗可以復用到js
,從而更有效的解決js
中的問題。
的確,面相對象是一個很有用的思考模塊,在分解真實世界、大型項目的維護上有很大的好處,但是卻缺少了函數式的靈巧。曾經想用完全面向對象的方式寫一個redux
,卻發現無法用這種方式寫出compose
這種神奇的東西。
或許是我還沒能在面相對象和函數式之間取得一種平衡,以取得面相對象和函數式共同的優點。
0x001 類
普通的類
-
普通的類
class Person{}
-
類表達式
// 匿名類 let Person=class{} // 具名類 let Person=class Person{}
0x001 初始化類和構造函數
實例化類
可以使用new
來調用一個類,從而實例化一個類實例
-
class Person{} new Person() // Person{}
-
構造函數
使用new
實例化一個類實例之后,將會自動調用該類的構造函數constructor
,並且可以傳遞參數class Person{ constructor(name, age){ console.log(name, age) } } new Person("jack", 23) // 'jack', 23
類變量
類中可以保存一些變量,在類中,可以通過this.variable_name
來訪問,在類外,可以通過instance_name.variable_name
只有類實例可以訪問他們,並且每個類實例的變量都是屬於每個類實例的。class Person { constructor(nickname, age){ this.nickname = nickname this.age = age } } console.log(Person.nickname) // undefined console.log(Person.age) // undefined let person=new Person("jack",23) console.log(person.nickname) // 'jack' console.log(person.age) // 23 let person2=new Person("maria",11) console.log(person2.nickname) // 'maria' console.log(person2.age) // 11
類方法
類方法是定義在類內部的函數,可以在類內部調用:this.function_name(params)
,也可以在實例上調用:instance_name.function_name(params)
class Person{ constructor(nickname, age){ this.nickname = nickname this.age =age } getNickname(){ return this.nickname } getAge(){ return this.age } summary(){ return `${this.nickname}:${this.age}` } } let person=new Person('jack', 23) console.log(person.getNickname()) // ''jack console.log(person.getAge()) // 23 console.log(person.summary()) // 'jack:23'
靜態方法
靜態方法是可以通過類直接調用的方法,不需要實例化class Person{ static sayHello(){ console.log('hello') } } Person.sayHello() // 'hello'
繼承
繼承就是將父類所有的方法和都繼承下來,包括構造函數
class Person{ constructor(nickname, age){ this.nickname = nickname this.age =age } getNickname(){ return this.nickname } getAge(){ return this.age } summary(){ return 'this is Person' } } class Male extends Person {} let male=new Male('jack',23) console.log(male.nickname) // 'jack' console.log(male.age) // 23 console.log(male.getNickname()) // 'jack' console.log(male.getAge()) // 23 console.log(male.summary()) // 'this is Person'
class Far { constructor(x, y) { this.x = x; this.y = y; } sum() { console.log(this.x + this.y); } } class Jc extends Far { constructor(x, y) { super(x, y); } } new Jc(1, 2).sum();
0x003 重寫
有時候我們不希望一個函數的作用和父類一致,比如在上面的栗子中,
male.summary()
返回this is Person
,不符合我們的逾期,我們希望返回this is Male
,這個時候就可以用到重寫,只要寫一個和父類相同名字和函數就行了,甚至參數個數不一致也不影響class Person{ constructor(nickname, age){ this.nickname = nickname this.age =age } getNickname(){ return this.nickname } getAge(){ return this.age } summary(){ return 'this is Person' } } class Male extends Person { summary(){ return 'this is Male' } } let male=new Male() console.log(male.summary()) // this is Male