1. <ul id="0c1fb"></ul>

      <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
      <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区

      RELATEED CONSULTING
      相關咨詢
      選擇下列產(chǎn)品馬上在線溝通
      服務時間:8:30-17:00
      你可能遇到了下面的問題
      關閉右側(cè)工具欄

      新聞中心

      這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
      一文看懂JS繼承

      繼承是OOP中大家最喜歡談論的內(nèi)容之一,一般來說,繼承都兩種方式:接口繼承和實現(xiàn)繼承而JavaScript中沒有接口繼承需要的方法,因此只能依靠實現(xiàn)繼承。
      在講繼承的實現(xiàn)之前,我們首先來回顧一下什么是繼承?繼承的作用是什么?

      10年積累的成都網(wǎng)站制作、網(wǎng)站設計經(jīng)驗,可以快速應對客戶對網(wǎng)站的新想法和需求。提供各種問題對應的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡服務。我雖然不認識你,你也不認識我。但先制作網(wǎng)站后付款的網(wǎng)站建設流程,更有宜秀免費網(wǎng)站建設讓你可以放心的選擇與我們合作。

      它可以使用現(xiàn)有類的所有功能,并在無需重新編寫原來的類的情況下對這些功能進行擴展。
      通過繼承創(chuàng)建的新類稱為“子類”或“派生類”。
      被繼承的類稱為“基類”、“父類”或“超類”。
      在清楚繼承的作用之后,下面我們來探討一下JS中的幾種繼承實現(xiàn)的方式:
      //混入式繼承(拷貝)//obj2繼承到obj1中的成員,可以直接將obj1中的成員拷貝到obj2中即可var obj1 = {name:"zs",age:10};var obj2 = {};// 將obj1中的成員拷貝到obj2中for (var key in obj1) {
      obj2[key] = obj1[key];
      }console.log(obj1);console.log(obj2);
      最終得到的obj2中的成員和obj1中的成員完全一致,當然,我們需要清除的是,此時的obj1和obj2是兩個不同的對象。
      混入式繼承方式看似很簡單,但是存在共享數(shù)據(jù)安全的問題。
      var obj1 = {name:"zs",age:10,car:{name:"mini"}};var obj2 = {};// 將obj1中的成員拷貝到obj2中for (var key in obj1) {
      obj2[key] = obj1[key];
      }//修改obj1對象中的car屬性
      obj1.car.name = "bus";
      console.log(obj1);console.log(obj2);
      當我們需要修改某些對象中的引用類型對象的時候,會造成其他相關的對象也被修改,這是我們不希望看到的。
      原型式繼承的實現(xiàn)
      回想一下,當我們在訪問一個對象中的成員的時候,首先是在當前對象中查找,如果找不到,就往上,在原型鏈中依次查找,如果在整個原型鏈中也不存在該成員,那么就返回undefined。
      所以,我們想要在A對象中訪問到B對象中的成員,除了將B中的成員添加到A中,如:混入式,我們也可以考慮將B中成員添加到A的原型鏈中,實現(xiàn)對象成員的共享。
      function Animal() {
      }
      Animal.prototype.name="animal";function Person() {
      }//修改Person的原型對象
      Person.prototype= Animal.prototype;

      Person.prototype.useTool = function () {
      console.log("use fire");
      }var p = new Person();console.log(p);var ani = new Animal();console.log(ani);
      畫圖分析:

      1. 最初,Animal和Person的兩個對象沒有任何關系,所以各自只能訪問各自的成員
        一文看懂JS繼承
      2. 現(xiàn)在,Person對象如果想要繼承Animal對象,只需要將Person的原型對象修改為Animal的原型對象即可
        一文看懂JS繼承
        這種方式實現(xiàn)的繼承稱之為原型繼承,實現(xiàn)也是比較方便的,當時和混入式一樣,存在數(shù)據(jù)共享的問題。
        原型鏈繼承的實現(xiàn)
        原型式繼承
        在前面的課程中,我們講了原型式的繼承,這種繼承方式是修改子類對象原型指向父類對象的原型,如前面的MyArray執(zhí)行的是Array的原型對象。
        這種方式存在問題是,只能繼承父類對象原型上的成員,但無法繼承父類對象中的成員。
        function Animal() {
        this.color="red";
        }
        Animal.prototype.weight=100;function Person() {
        }
        Person.prototype = Animal.prototype;var p = new Person();console.log(p);
        Person.prototype = Animal.prototype;原型式的繼承
        此時創(chuàng)建出來的Person對象p可以訪問Animal中的weight屬性,但是無法訪問color屬性。看圖理解
        一文看懂JS繼承
        那么,如果我們既要繼承原型對象中的成員,也要繼承實例對象中的成員,就應該使用這一節(jié)中的原型鏈繼承
        function Animal() {
        this.color="red";
        }
        Animal.prototype.weight=100;function Person() {
        }
        Person.prototype = new Animal();var p = new Person();console.log(p.color);//red

      一文看懂JS繼承
      使用原型鏈繼承方式能夠繼承到更多的成員。但是依然存在問題:

      1. 共享的問題
      2. 無法向構造器傳參
        復雜的原型鏈繼承示例---
        Object-Animal-Person-Boy
        Object.create方法的基本使用
        在Object的構造函數(shù)上存在一個create方法,該方法的作用是用來創(chuàng)建對象的。
        該方法可以接收的參數(shù)有一下兩種
      3. null

      4. 創(chuàng)建一個空對象,這個空對象中連最基本的原型對象都沒有的

      5. 對象

      6. 創(chuàng)建傳遞進來的對象,并設置該對象的原型對象為當前的參數(shù)

      7. 一文看懂JS繼承
        該方法的使用率比較低,要求大家知道存在這樣的一種創(chuàng)建對象的方式即可。
        call方法和apply方法的基本使用
        call和apply方法作用:

      8. 方法借用2. 設置方法中this的指向
        var obj1 = {
        name:"Neld",
        age:10,
        showInfo:function () {
        console.log("name:"+this.name,"age:"+this.age);
        }
        }var obj2 = {
        name:"Lily",
        age:12
        }
        obj1.showInfo();//name:Neld age:10
        obj2.showInfo();//obj2.showInfo is not a function
        obj1對象中有showInfo方法,而obj2對象中沒有,所以如果直接使用obj2調(diào)用showInfo方法的時候拋出錯誤信息。
        如果我們臨時需要使用obj2調(diào)用showInfo方法來打印出name和age屬性的值,此時可以使用這里的call或者apply方法來實現(xiàn)。
        obj1.showInfo.call(obj2);//name:Lily age:12
        obj1.showInfo.apply(obj2);//name:Lily age:12
        這就是把obj1中的showInfo方法借用給obj2使用。
        同時我們觀察到,在showInfo方法中使用到了this關鍵字,在obj2借用該方法的時候,其中的this已經(jīng)指向了obj2對象,這就要達到修改方法中this關鍵字的指向的目的。
        call和apply方法的作用是完全一樣的,那么他們的區(qū)別是什么呢?繼續(xù)往下分析。
        var obj1 = {
        name:"Neld",
        age:10,
        add : function (a, b) {
        return a + b;
        }
        }var obj2 = {
        name:"Lily",
        age:12
        }console.log(obj1.add.call(obj2, 1, 2));//3//console.log(obj1.add.apply(obj2, 1, 2));//CreateListFromArrayLike called on non-objectconsole.log(obj1.add.apply(obj2, [2, 2]));//4
        在obj1中定義一個帶有兩個參數(shù)的方法,obj2中沒有,問題一樣,obj2也要使用到obj1中的add方法,此時使用call或者apply借用即可。
        此時新的問題是,在調(diào)用add方法的時候參數(shù)應該如何傳遞?
        call方法:
        ? 將this指向的對象作為第一個參數(shù),其他參數(shù)依次傳遞即可
        apply方法:
        ? 將this指向的對象作為第一個參數(shù),其他參數(shù)封裝到數(shù)組中傳遞
        ? 如果沒有使用數(shù)組,程序報錯。
        以上就是call和apply的基本使用,這兩個方法在后續(xù)的課程中會大量的使用到,所以必須引起重視。
        借用構造函數(shù)繼承說明
        所謂借用構造函數(shù),就是在子構造函數(shù)中調(diào)用父構造函數(shù),達到繼承并向父構造函數(shù)傳參的目的。
        function SuperClass(name,age) {
        this.name = name;
        this.age = age;
        }
        SuperClass.prototype.fun1 = function () {
        console.log("name:",this.name,"age:",this.age);
        }function SubClass(color) {
        this.color = color;
        }
        SubClass.prototype = new SuperClass("xxx",10);//繼承父構造函數(shù)并設置name和age的值
        SubClass.prototype.fun2 = function () {
        console.log("color:",this.color);
        }var sub = new SubClass("red", "Neld", 10);var sub2 = new SubClass("red", "Lily", 12);console.log(sub);console.log(sub2);
        上面是原型鏈的繼承,這種方式存在一個問題是,在創(chuàng)建不同對象的時候,無法為其繼承過來的成員賦值。
        這里的sub和sub2兩個對象的name和age屬性值都是“xxx”和10,很明顯是不滿足我們需求的。
        那么我們來看看借用構造函數(shù)是否能解決這個問題呢?
        function SuperClass(name,age) {
        this.name = name;
        this.age = age;
        }
        SuperClass.prototype.fun1 = function () {
        console.log("name:",this.name,"age:",this.age);
        }function SubClass(color, name, age) {
        this.newMethod = SuperClass;//①
        this.newMethod(name, age);//②
        this.color = color;
        delete this.newMethod;//③
        }//SubClass.prototype = new SuperClass();
        SubClass.prototype.fun2 = function () {
        console.log("color:",this.color);
        }var sub = new SubClass("red", "Neld", 10);var sub2 = new SubClass("red", "Lily", 12);console.log(sub);console.log(sub2);
        ①、②、③處代碼是實現(xiàn)借用構造函數(shù)的關鍵。下面一一作出解釋:
        ①:將父對象的構造函數(shù)設置為子對象的成員
        ②:調(diào)用這個方法,想過類似于將父構造函數(shù)的代碼放在子構造函數(shù)中來執(zhí)行
        function SubClass(color, name, age) {
        this.newMethod = SuperClass;
        this.name = name;//父構造函數(shù)中的代碼
        this.age = age;//父構造函數(shù)中的代碼
        this.color = color;
        delete this.newMethod;
        }
        這樣看應該更直觀一點,執(zhí)行之后就是在為當前創(chuàng)建出來的對象封裝name和age屬性。
        ③:在子構造函數(shù)中,newMethod僅僅為了在②調(diào)用父構造函數(shù)使用,用完之后也就沒了價值,所以,直接刪除該方法即可
        一文看懂JS繼承
        可以看到,借用構造函數(shù)繼承方式解決了原型鏈及繼承的問題。
        下面再看看另外一種借用構造函數(shù)的實現(xiàn)方式(使用call或apply):
        function SubClass(color, name, age) {
        //SuperClass.call(this,name,age);
        SuperClass.apply(this,[name,age]);
        this.color = color;
        }
        我們可以使用call或apply更簡單快捷的實現(xiàn)和上面一樣的效果。
        以上就是借用構造函數(shù)繼承(也要對象冒充)的兩種實現(xiàn)方式。當然,這種繼承方式都存在下面兩個問題:
      9. 如果父子構造函數(shù)存在相同的成員,那么子構造函數(shù)會覆蓋父構造函數(shù)中的成員
      10. 不能繼承原型鏈中的成員
        組合繼承的基本結(jié)構
        基于原型鏈繼承和借用構造函數(shù)繼承兩種方式存在的問題,我們提出一個解決方案---組合繼承,就是兩種一起使用。
        function SubClass(color, name, age) {
        //SuperClass.call(this,name,age);
        SuperClass.apply(this,[name,age]);//繼承構造函數(shù)中的成員
        this.color = color;
        }

      SubClass.prototype = new SuperClass();//繼承原型鏈上的成員
      總結(jié): ECMAScript 實現(xiàn)繼承的方式不止一種。這是因為 JavaScript 中的繼承機制并不是明確規(guī)定的,而是通過模仿實現(xiàn)的。這意味著所有的繼承細節(jié)并非完全由解釋程序處理。作為開發(fā)者,你有權決定最適用的繼承方式。
      繪制完整的原型鏈結(jié)構圖
      這一節(jié)重點探討函數(shù)對象的原型鏈結(jié)構。完整的結(jié)構圖如下:
      一文看懂JS繼承
      說了這么多,其實核心只有一個:屬性共享和獨立的控制,當你的對象實例需要獨立的屬性,所有做法的本質(zhì)都是在對象實例里面創(chuàng)建屬性。若不考慮太多,你大可以在Person里面直接定義你所需要獨立的屬性來覆蓋掉原型的屬性。總之,使用原型繼承的時候,要對于原型中的屬性要特別注意,因為他們都是牽一發(fā)而動全身的存在。


      文章標題:一文看懂JS繼承
      網(wǎng)站地址:http://www.ef60e0e.cn/article/peehjc.html
      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区
      1. <ul id="0c1fb"></ul>

        <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
        <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

        霍林郭勒市| 南澳县| 乌苏市| 富宁县| 沅陵县| 乌苏市| 南城县| 比如县| 云和县| 巫溪县| 东城区| 且末县| 图片| 城固县| 蕉岭县| 南昌县| 龙江县| 武夷山市| 乳山市| 永顺县| 连江县| 汕头市| 新蔡县| 凤山县| 左权县| 蛟河市| 石林| 醴陵市| 麻栗坡县| 壤塘县| 陇西县| 余姚市| 广安市| 西藏| 永定县| 黔江区| 高安市| 镇远县| 垣曲县| 讷河市| 法库县|