<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 原型繼承 在傳統的基于Class的語言如Java、C++中,繼承的本質是擴展一個已有的Class,并生成新的Subclass。 由于這類語言嚴格區分類和實例,繼承實際上是類型的擴展。但是,JavaScript由于采用原型繼承,我們無法直接擴展一個Class,因為根本不存在Class這種類型。 但是辦法還是有的。我們先回顧`Student`構造函數: ``` function Student(props) { this.name = props.name || 'Unnamed'; } Student.prototype.hello = function () { alert('Hello, ' + this.name + '!'); } ``` 以及`Student`的原型鏈: ![js-proto](img/l6.png) 現在,我們要基于`Student`擴展出`PrimaryStudent`,可以先定義出`PrimaryStudent`: ``` function PrimaryStudent(props) { // 調用Student構造函數,綁定this變量: Student.call(this, props); this.grade = props.grade || 1; } ``` 但是,調用了`Student`構造函數不等于繼承了`Student`,`PrimaryStudent`創建的對象的原型是: ``` new PrimaryStudent() ----> PrimaryStudent.prototype ----> Object.prototype ----> null ``` 必須想辦法把原型鏈修改為: ``` new PrimaryStudent() ----> PrimaryStudent.prototype ----> Student.prototype ----> Object.prototype ----> null ``` 這樣,原型鏈對了,繼承關系就對了。新的基于`PrimaryStudent`創建的對象不但能調用`PrimaryStudent.prototype`定義的方法,也可以調用`Student.prototype`定義的方法。 如果你想用最簡單粗暴的方法這么干: ``` PrimaryStudent.prototype = Student.prototype; ``` 是不行的!如果這樣的話,`PrimaryStudent`和`Student`共享一個原型對象,那還要定義`PrimaryStudent`干啥? 我們必須借助一個中間對象來實現正確的原型鏈,這個中間對象的原型要指向`Student.prototype`。為了實現這一點,參考道爺(就是發明JSON的那個道格拉斯)的代碼,中間對象可以用一個空函數`F`來實現: ``` // PrimaryStudent構造函數: function PrimaryStudent(props) { Student.call(this, props); this.grade = props.grade || 1; } // 空函數F: function F() { } // 把F的原型指向Student.prototype: F.prototype = Student.prototype; // 把PrimaryStudent的原型指向一個新的F對象,F對象的原型正好指向Student.prototype: PrimaryStudent.prototype = new F(); // 把PrimaryStudent原型的構造函數修復為PrimaryStudent: PrimaryStudent.prototype.constructor = PrimaryStudent; // 繼續在PrimaryStudent原型(就是new F()對象)上定義方法: PrimaryStudent.prototype.getGrade = function () { return this.grade; }; // 創建xiaoming: var xiaoming = new PrimaryStudent({ name: '小明', grade: 2 }); xiaoming.name; // '小明' xiaoming.grade; // 2 // 驗證原型: xiaoming.__proto__ === PrimaryStudent.prototype; // true xiaoming.__proto__.__proto__ === Student.prototype; // true // 驗證繼承關系: xiaoming instanceof PrimaryStudent; // true xiaoming instanceof Student; // true ``` 用一張圖來表示新的原型鏈: ![js-proto-extend](img/l7.png) 注意,函數`F`僅用于橋接,我們僅創建了一個`new F()`實例,而且,沒有改變原有的`Student`定義的原型鏈。 如果把繼承這個動作用一個`inherits()`函數封裝起來,還可以隱藏`F`的定義,并簡化代碼: ``` function inherits(Child, Parent) { var F = function () {}; F.prototype = Parent.prototype; Child.prototype = new F(); Child.prototype.constructor = Child; } ``` 這個`inherits()`函數可以復用: ``` function Student(props) { this.name = props.name || 'Unnamed'; } Student.prototype.hello = function () { alert('Hello, ' + this.name + '!'); } function PrimaryStudent(props) { Student.call(this, props); this.grade = props.grade || 1; } // 實現原型繼承鏈: inherits(PrimaryStudent, Student); // 綁定其他方法到PrimaryStudent原型: PrimaryStudent.prototype.getGrade = function () { return this.grade; }; ``` ## 小結 JavaScript的原型繼承實現方式就是: 1. 定義新的構造函數,并在內部用`call()`調用希望“繼承”的構造函數,并綁定`this`; 2. 借助中間函數`F`實現原型鏈繼承,最好通過封裝的`inherits`函數完成; 3. 繼續在新的構造函數的原型上定義新方法。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看