<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>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                [TOC] # 繼承 ## 原型鏈繼承 核心:將父類的實例作為子類的原型 ~~~ function Parent () { this.names = ['kevin', 'daisy']; } Parent.prototype.getName = function () { return this.name } function Child () { } Child.prototype = new Parent(); var child1 = new Child(); child1.names.push('yayu'); console.log(child1.names); // ["kevin", "daisy", "yayu"] var child2 = new Child(); console.log(child2.names); // ["kevin", "daisy", "yayu"] ~~~ 特點: * 非常純粹的繼承關系,實例是子類的實例,也是父類的實例 * 父類新增原型方法/原型屬性,子類都能訪問到 * 簡單,易于實現 缺點 * 要想為子類新增屬性和方法,必須要在`new Animal()`這樣的語句之后執行,不能放到構造器中 * 無法實現多繼承 * 來自原型對象的所有屬性被所有實例共享(來自原型對象的引用屬性是所有實例共享的) * 創建子類實例時,無法向父類構造函數傳參 <br> ## 構造函數繼承 核心:使用父類的構造函數來增強子類實例,等于是復制父類的實例屬性給子類(沒用到原型) ~~~ function Parent () { this.names = ['kevin', 'daisy']; } Parent.prototype.say = function () {}; function Child () { Parent.call(this); this.type = 'child1'; } var child1 = new Child(); child1.names.push('yayu'); child1.names // ["kevin", "daisy", "yayu"] var child2 = new Child(); child2.names // ["kevin", "daisy"] new Child1().say() // undefined ~~~ 特點: * 解決了1中,子類實例共享父類引用屬性的問題 * 創建子類實例時,可以向父類傳遞參數 * 可以實現多繼承(call多個父類對象) 缺點: * 實例并不是父類的實例,只是子類的實例 * 只能繼承父類的實例屬性和方法,不能繼承原型屬性/方法 * 無法實現函數復用,每個子類都有父類實例函數的副本,影響性能 <br> ## 實例繼承 核心:為父類實例添加新特性,作為子類實例返回 ~~~ // 定義一個動物類 function Animal (name) { // 屬性 this.name = name || 'Animal'; // 實例方法 this.sleep = function(){ console.log(this.name + '正在睡覺!'); } } // 原型方法 Animal.prototype.eat = function(food) { console.log(this.name + '正在吃:' + food); }; function Cat(name){ var instance = new Animal(); instance.name = name || 'Tom'; return instance; } // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // true console.log(cat instanceof Cat); // false ~~~ 特點: * 不限制調用方式,不管是`new 子類()`還是`子類()`,返回的對象具有相同的效果 缺點: * 實例是父類的實例,不是子類的實例 * 不支持多繼承 <br> ## 組合繼承 ~~~ function Parent3 () { this.name = 'parent3'; this.play = [1, 2, 3]; } function Child3 () { Parent3.call(this); this.type = 'child3'; } Child3.prototype = new Parent3(); var s3 = new Child3(); var s4 = new Child3(); s3.play.push(4); console.log(s3.play, s4.play); ~~~ 缺點 * 父級的構造函數執行了2次 <br> 優化 ~~~ function Parent4 () { this.name = 'parent4'; this.play = [1, 2, 3]; } function Child4 () { Parent4.call(this); this.type = 'child4'; } Child4.prototype = Parent4.prototype; // 同時Child4的實例的constructor也指向Parent4~~~ var s5 = new Child4(); var s6 = new Child4(); console.log(s5, s6); console.log(s5 instanceof Child4, s5 instanceof Parent4); // true true console.log(s5.constructor); // Parent4 ~~~ 特點: * 彌補了方式2的缺陷,可以繼承實例屬性/方法,也可以繼承原型屬性/方法 * 既是子類的實例,也是父類的實例 * 不存在引用屬性共享問題 * 可傳參 * 函數可復用 缺點: * 調用了兩次父類構造函數,生成了兩份實例(子類實例將子類原型上的那份屏蔽了) <br> ## 寄生組合式繼承 核心:通過寄生方式,砍掉父類的實例屬性,這樣,在調用兩次父類的構造的時候,就不會初始化兩次實例方法/屬性,避免的組合繼承的缺點 ~~~ function Parent (name) { this.name = name; this.colors = ['red', 'blue', 'green']; } Parent.prototype.getName = function () { console.log(this.name) } function Child (name, age) { Parent.call(this, name); this.age = age; } var F = function () {}; F.prototype = Parent.prototype; Child.prototype = new F(); Child.prototype.constructor = Child; var child1 = new Child('kevin', '18'); ~~~ 優化 ~~~ function Parent5 () { this.name = 'parent5'; this.play = [1, 2, 3]; } function Child5 () { Parent5.call(this); this.type = 'child5'; } Child5.prototype = Object.create(Parent5.prototype); Child5.prototype.constructor = Child5 var s7 = new Child5() console.log(s7 instanceof Child5, s7 instanceof Parent5); // true true console.log(s7.constructor) // function Child (name, age) { Parent.call(this, name); this.age = age;} ~~~ <br> ## Class ~~~ class Animal{ constructor(){ console.log("Animal Constructor"); } } Animal.prototype.species = "動物"; class Cat extends Animal{ constructor(name,color){ super(); this.name = name; this.color = color; } } let cat1 = new Cat("測試1","紅色") console.log(cat1); ~~~ <br> <br> # 參考資料 * [JavaScript深入之繼承的多種方式和優缺點](https://github.com/mqyqingfeng/Blog/issues/16) * [JS實現繼承的幾種方式](https://www.cnblogs.com/humin/p/4556820.html) * [JavaScript繼承](https://github.com/273539918/blog/issues/1) * 前端跳槽面試必備技巧
                  <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>

                              哎呀哎呀视频在线观看