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

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 面向對象復習 ## 普通構造函數 ~~~ function Person(name, age) { ?this.name = name; ?this.age = age; } Person.prototype.say = function(){ ?console.log('i can say') } Person.go = function () { ?console.log('走一下'); } ~~~ ~~~ var p1 = new Person('小白',10); console.log(p1); p1.say(); Person.go(); ~~~ ## class關鍵詞 ~~~ class Per{ ?constructor(name,age){ ? ?this.name ?= name; ? ?this.age = age; } ?say(){ ? ?console.log('i can say') } ?static go(){ ? ?console.log('要走一走') } } var p2 ?= new Per('小黑',15); console.log(p2); p2.say(); Per.go(); ~~~ # 面向對象繼承 實現人類和中國人(重點) 與美國人(輔助了解) ## 實現人類 ~~~ function Person(name,age){ ?this.name = name; ?this.age = age; } ? Person.prototype.say = function(){ ?console.log('i can say '); } ~~~ ## 原型鏈繼承 ~~~ ? //原型鏈繼承 ? function Chinese(skin,language){ ?this.skin = skin; ?this.language = language; } Chinese.prototype = new Person(); var p1 = new Chinese('黃色','中文') console.log(p1); p1.say(); ~~~ ### 圖解 ![](https://box.kancloud.cn/513784702990bcf3e88ffa1338f18082_1063x611.png) ### 問題 Chinese構造函數的原型對象的constructor指向誰。它指向Person,原因是為什么因為new Person()身上沒有constructor,它通過`__proto__`指向Person的原型對象(Person.prototype),這個對象的constructor指向Person。 構造函數的原型對象的constructor指向構造函數自身,按照這個原則我們這個代碼或者關系圖是有錯誤的。如何解決? 將new Person()手動添加constructor并且手動指向Chinese。即可修復。 ### 修改后的代碼 ~~~ //原型鏈繼承 function Chinese(skin,language){ ?this.skin = skin; ?this.language = language; } var person1 = new Person(); person1.constructor = Chinese; Chinese.prototype = person1; var p1 = new Chinese('黃色','中文') console.log(p1); p1.say(); console.log(Chinese.prototype.constructor) ~~~ ### 完成后的圖 ![](https://box.kancloud.cn/e6607791dca2e0bce7cd3239d6ba8231_1063x621.png) ## 構造函數繼承(對象冒充繼承) 上面的繼承只能繼承原型對象的方法。并不能繼承父類的屬性。如何解決?可以通過關鍵字call或者applay來實現當前類借用擴充。不屬于原型或者原型鏈的操作方式。幫不需要畫圖。 ~~~ // 構造函數繼承 對象冒充 function Chinese(skin,language,name,age){ ?this.skin = skin; ?this.language = language; ?Person.call(this,name,age); } var p1 = new Chinese('黃色','中文','小白',18); console.log(p1); ~~~ ## 組合繼承 組合繼承其實就是原型鏈接繼承和構造函數繼承的結合體 ~~~ //原型鏈繼承 function Chinese(skin,language,name,age){ this.skin = skin; this.language = language; Person.call(this,name,age);// 第一次調用父類 } var person1 = new Person(); //第二次調用父類 person1.constructor = Chinese; Chinese.prototype = person1; var p1 = new Chinese('黃色','中文','小白',18); console.log(p1); p1.say(); ~~~ ### 問題 組合繼承的問題在于在子類中調用父類一次。會導致性能浪費。 ![](https://box.kancloud.cn/a5d66c36dcdef7d29ac0a64f7e3d5114_836x229.png) ## 原型式繼承(原型繼承) ### 簡易版 ~~~ function Chinese(skin,language,name,age){ this.skin = skin; this.language = language; } Chinese.prototype = Person.prototype; var p1 = new Chinese('黃色','中文') console.log(p1); p1.say(); function America(skin,language,name,age){ this.skin = skin; this.language = language; } Chinese.prototype = Person.prototype; var a1 = new Chinese('白色','英語') console.log(a1); a1.say(); ~~~ ### 圖解 ![](https://box.kancloud.cn/337662c67140ef6630e1dfa20777ca40_1624x633.png) ### 問題 如果把Chinese.prototype.say方法修改會產生什么問題?修改代碼嘗試。 ~~~ Chinese.prototype.say = function(){ console.log('我是中國人') } ~~~ 完整代碼如下 ~~~ function Chinese(skin,language,name,age){ this.skin = skin; this.language = language; } Chinese.prototype = Person.prototype; Chinese.prototype.say = function(){ console.log('我是中國人') } var p1 = new Chinese('黃色','中文') console.log(p1); p1.say(); function America(skin,language,name,age){ this.skin = skin; this.language = language; } Chinese.prototype = Person.prototype; var a1 = new Chinese('白色','英語') console.log(a1); a1.say(); ~~~ ### 執行結果 ~~~ Chinese {skin: "黃色", language: "中文"} 我是中國人 Chinese {skin: "白色", language: "英語"} 我是中國人 ~~~ 我們發現一旦對say方法進行修改,那么導致,繼承于父類Person的所有子類的原型對象的say方法都發生改變。原因是因為他們用的同一份。如何解決? ### 改造原型繼承 其實想法很簡單,又要避開重復實例化父類多次,又要實現不同子類繼承同一父類,在原型對象方法修改時不會影響其它子類。 **看下圖,大家可以簡單理解,其實中間圈中的部分不過就是搭了個橋,讓子類修改原型時候,不會直接修改父類原型。而是創建一個新的空類,這個空類使用原型式繼承父類原型對象。再通過實例化一個對象作為子類Chinese的原型對象。** **這樣的話子類的實例 p 可以通過`__proto__`查找到父類 Chinese 的原型對象,同樣的也可以通過原型對象的`__proto__`來查找到Person類的原型對象的公共方法。 這樣原型鏈得到繼承。** **同時我們修改子類Chinese的原型對象也僅僅是修改了f對象的功能。沒有修改 父類Person類的原型對象。** **簡單理解這個圖的意思就就我們將父類和子類中間橫插一腳。** ![](https://box.kancloud.cn/db9bd60c32e3c97f1abb6631c3f1119a_1107x720.png) ### 簡化后的圖 ![](https://box.kancloud.cn/ee91e6f6519c7d3ac6f33cc351a0b72e_675x272.png) ### 代碼實現 ~~~ function Chinese(skin,language,name,age){ this.skin = skin; this.language = language; } // Chinese.prototype = Person.prototype; // 原型繼承改造 //1.創建F構造函數,并且返回實例 new F(); function object(parentPro){ var F = function () {} F.prototype = parentPro; return new F(); } //將返回的實例作為子類的原型對象,同時修改子類原型對象的constructor指向子類。 function inhert(par,child) { var mid = object(par.prototype); mid.constructor = child; child.prototype = mid; } inhert(Person,Chinese); ~~~ ## 寄生式組合繼承 其實就是原型式繼承改造后和構造函數繼承的結合版。 ~~~ // Chinese.prototype = Person.prototype; // 原型繼承改造 //1.創建F構造函數,并且返回實例 new F(); function object(parentPro){ var F = function () {} F.prototype = parentPro; return new F(); } //2.將返回的實例作為子類的原型對象,同時修改子類原型對象的constructor指向子類。 function inhert(par,child) { var mid = object(par.prototype); mid.constructor = child; child.prototype = mid; } function Chinese(skin,language,name,age){ this.skin = skin; this.language = language; Person.call(this,name,age) } inhert(Person,Chinese); var p1 = new Chinese('黃皮膚','中文','小白',18) console.log(p1); p1.say(); ~~~ ![](https://box.kancloud.cn/f72d0892235df210e070ab0fa13d26e2_672x228.png) # class繼承 ~~~ class Person{ constructor(name,age){ this.name = name; this.age = age; } say(){ console.log(this.name) } } class Chinese extends Person{ constructor(name,age,skin,language){ super(name,age); this.skin = skin; this.language = language; } } var p = new Chinese('小黑',18,'白','漢語') console.log(p); ~~~ ## 注意事項 如果子類要繼承父類,子類的構造函數中必須書寫super() 而且必須寫在首行。它其實就相當于構造函數中的對象冒充寫法。 ![](https://box.kancloud.cn/2fb6b8d0be4a510c16c52a9a45493064_608x263.png) ## 給父類添加靜態方法 父類的靜態方法可以給子類繼承靜態方法。 ~~~ class Person{ constructor(name,age){ this.name = name; this.age = age; } say(){ console.log(this.name) } static go(){ console.log('i can go') } } ~~~ ~~~ Person.go();//i can go Chinese.go();//i can go ~~~
                  <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>

                              哎呀哎呀视频在线观看