【前言】
近來因為講課需要,涉及到使用JavaScript中的繼承,但發現遇上不懂的同學,無法用一句話帶過,因為周邊涉及的知識點比較多,因此決定系統的來說一說,我先簡單用一點圖來描述什么是繼承,(不懂的同學可以先忽略英文)

請先忽略prototype等看不懂的單詞,可以看到祖宗改變就能影響后代,這樣也就讓我們能改一處,多出發生變化,減輕了作業量,提高了效率,
【繼承的思路】
總的來說繼承可以理解為設定屬性或功能的多復用,那么大致有2條路子實作該功能,
1:祖宗建構式的原型,其是創建物件時參照的模板,所有實體共享該原型物件的是屬性及函式,
2:祖宗建構式本身的復用,在子孫建構式內部呼叫祖宗的建構式,因此執行了祖宗的構造方法,從而子孫享有祖宗構造程序,
【建構式繼承】
重點就是子類呼叫父類建構式來創建物件
// 人類
function People () {
this.description = '人類';
}
// 學生
function Student () {
// 呼叫People函式,改變this指向
People.call(this);
}
var s = new Student();
s.description; // 人類
【原型繼承】
重點是子類使用父類原型來共享
// 人類
function People () {}
People.prototype.description = '人類';
var p = new People();
// 學生
function Student () {
}
// 原型繼承
Student.prototype = People.prototype;
var s = new Student();
s.description; // 人類
p.description; // 人類
【出現問題】
我們看到上面例子會帶來一個很簡單的問題,那就是 Student.prototype和People.prototype是同一個原型,當我們去改動任何一個原型的時候,將會影響Student和People的實體,試想People改動影響Student也許我們覺得還ok,可是反之,就感覺不對了,
【原型:父類實體繼承】
我們知道 new 父類()得到的結果是和父類原型息息相關的,因此為了避免Student.prototype和People.prototype是同一個物件,而new People()創建的物件是根據People.prototype來的,所以我們用一個父類的實體來代替原型,從而避免上述問題
// 人類
function People () {
}
People.prototype.description = '人類';
// 學生
function Student () {
}
// 原型繼承
Student.prototype = new People();
var s = new Student();
s.description; // 人類
【組合繼承】
但同時,我們需要父類建構式的執行獲取其他屬性,就需要使用到組合繼承的方式了,也就是【原型繼承】+【建構式繼承】
// 人類
function People (newProps) {
this.newProps = newProps;
}
People.prototype.description = '人類';
// 學生
function Student () {
// 呼叫父類建構式
People.call(this);
}
// 原型繼承
Student.prototype = new People();
var s = new Student();
s.description; // 人類
s.newProps; // xxx
這里稍有不慎你可能會看到

都是因為沒有傳遞引數的問題,那原型上這個undefine顯得不好看,而我們傳遞該值又顯得沒有意義,從記憶體角度來說,我們只是需要原型而不是需要走建構式呀,
【新建物件繼承】
// 人類
function People (newProps) {
this.newProps = newProps;
}
People.prototype.description = '人類';
// 學生
function Student () {
// 呼叫父類建構式
People.call(this);
}
// 原型繼承
Student.prototype = Object.create(People.Prototype);
var s = new Student();
s.description; // 人類
s.newProps; // xxx
【總結】
JS中的繼承主要分為兩條線即兩種思路:
- 根據父類建構式
- 根據原型
由于僅靠建構式構造出的實體,我們針對方法不太會使用this.fn = function(){}來浪費記憶體,因此會使用到原型,而原型又存在相同物件指向的問題,因此創建一個新的物件,然后新物件可能需要引數,會導致子類原型看起來不好看,這樣我們使用Object.create(父類原型),同時,如果父類建構式內的屬性我們需要,那么還需要組合起來呼叫,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/141461.html
標籤:JavaScript
