ES5裡類的建立和繼承
JS裡類的建立
JS裡類就是方法,建立一個類其實就是定義一個方法,比如:
function Person() { this.name = 'tomcat'; this.age = 20; }
這就定義了一個Person
類,要使用的話,需要new
一個例項,如下
var p = new Person(); console.log(p.name); console.log(p.age);
類裡當然也可以定義方法了,js裡類本身就是方法,定義類的方法,就是在這個方法裡寫匿名方法
function Person() { this.name = 'tomcat'; this.age = 20; this.run = function() { console.log(`${name} is running...`); } }
也可以通過原型鏈prototype
來定義方法
// 原型鏈方式定義屬性 Person.prototype.sex = 'male'; // 原型鏈方式定義方法 Person.prototype.work = function() { console.log(`${this.name} is working...`); }
這樣定義的方法是個例項方法,呼叫要使用類的例項來呼叫,如下
var p = new Person(); p.run(); p.work();
通過構造方法定義方法和原型鏈定義方法區別:原型鏈方式定義的方法可以被多個例項共享
上面說了在類裡定義方法,這種方法是例項方法,如何定義靜態方法呢?
Person.getInfo = function() { console.log('i am an static method!!'); } // 呼叫直接使用類名呼叫 Person.getInfo();
測試結果是,靜態方法裡沒法用this.name
來獲取構造方法裡的屬性
JS裡類的繼承
JS裡類的繼承有兩種,原型鏈
物件冒充
兩種方式,而且這兩種方式可以組合使用
冒充實現
定義一個類People
類,讓它繼承Person
類
function People() { Person.call(this); } // 呼叫 var people = new People(); people.run(); // 正常執行 people.work(); // 報錯
物件冒充方式繼承類,只能繼承構造方法裡定義的屬性和方法,原型鏈定義的屬性和方法是沒法繼承過來的
原型鏈繼承
還是定義一個People
類,通過原型鏈繼承
function People() { } People.prototype = new Person(); // 呼叫 var people = new People(); people.run(); people.work();
原型鏈繼承可以繼承構造方法裡的屬性和方法也可以繼承原型鏈裡的屬性和方法
但是原型鏈繼承也是有問題的,看下面例子
如果Person
物件裡的屬性是通過引數來例項化的
function Person(name, age) { this.name = name; this.age = age; this.run = function() { console.log(`name: ${this.name}, age: ${this.age}`); } } // 下面通過原型鏈繼承 function People(name, age) { } People.prototype = new Person(); var people = new People('jetty', 22); people.run(); // name: undefined, age: undefined
可以看到例項化子類的時候沒法給父類傳參
原型鏈+物件冒充
還是上面那個例子
function Person(name, age) { this.name = name; this.age = age; this.run = function() { console.log(`name: ${this.name}, age: ${this.age}`); } } Person.prototype.work = function() { console.log(`${this.name} is working...`); } // 下面通過原型鏈繼承 function People(name, age) { Person.call(this, name, age); } People.prototype = new Person(); var people = new People('jetty', 22); people.run(); // name: jetty, age: 22 people.work();
只需要在建立子類的構造方法裡通過物件冒充的方式繼承父類,並把引數傳進去就可以了,下面列印就有子類傳遞的引數了
上面那種方法中原型鏈的繼承用的是通過new Person()
的方式來實現的,但上面子類裡已經通過物件冒充的方式把父類的構造方法和屬性都繼承了,下面繼承原型鏈屬性方法就有些重複了,所以也可以寫成下面這樣
function Person(name, age) { this.name = name; this.age = age; this.run = function() { console.log(`name: ${this.name}, age: ${this.age}`); } } Person.prototype.work = function() { console.log(`${this.name} is working...`); } // 下面通過原型鏈繼承 function People(name, age) { Person.call(this, name, age); } People.prototype = Person.prototype; // 這裡只繼承父類的原型鏈屬性和方法,構造方法裡的屬性和方法就不繼承了 var people = new People('jetty', 22); people.run(); // name: jetty, age: 22 people.work();
參考
- https://www.bilibili.com/video/av38379328?p=5
原文連結: