<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智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                [TOC] >[success] # Javascript面向對象編程(二):構造函數的繼承 在寫之前先發一下參考大佬阮一峰的文章地址 [Javascript面向對象編程(二):構造函數的繼承](http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_inheritance.html) 因為是參考大佬的案例總結知識嘛。 ~~~ 今天要介紹的是,對象之間的"繼承"的五種方法,比如,現在有一個"動物"對象的構造函數。    function Animal(){ this.species = "動物"; } 還有一個"貓"對象的構造函數。 function Cat(name,color){ this.name = name; this.color = color; } 怎樣才能使"貓"繼承"動物"呢? ~~~ <br/> >[success] ## 一、 構造函數綁定 ~~~ 第一種方法也是最簡單的方法,使用call或apply方法,將父對象的構造函數綁定在子對象上,即在子對象 構造函數中加一行:   function Cat(name,color){     Animal.apply(this, arguments);     this.name = name;     this.color = color;   }   var cat1 = new Cat("大毛","黃色");   alert(cat1.species); // 動物 ~~~ <br/> >[success] ## 二、 prototype模式 ~~~ 第二種方法更常見,使用prototype屬性,如果"貓"的prototype對象,指向一個Animal的實例,那么所有"貓" 的實例,就能繼承Animal了。   Cat.prototype = new Animal();   Cat.prototype.constructor = Cat;   var cat1 = new Cat("大毛","黃色");   alert(cat1.species); // 動物 代碼的第一行,我們將Cat的prototype對象指向一個Animal的實例。 Cat.prototype = new Animal(); 它相當于完全刪除了prototype 對象原先的值,然后賦予一個新值。但是,第二行又是什么意思呢?   Cat.prototype.constructor = Cat; 原來,任何一個prototype對象都有一個constructor屬性,指向它的構造函數。如果沒有"Cat.prototype = new Animal();"這一行, Cat.prototype.constructor是指向Cat的;加了這一行以后,Cat.prototype.constructor指向Animal。 alert(Cat.prototype.constructor == Animal); //true 更重要的是,每一個實例也有一個constructor屬性,默認調用prototype對象的constructor屬性。 alert(cat1.constructor == Cat.prototype.constructor); // true 因此,在運行"Cat.prototype = new Animal();"這一行之后,cat1.constructor也指向Animal! alert(cat1.constructor == Animal); // true 這顯然會導致繼承鏈的紊亂(cat1明明是用構造函數Cat生成的),因此我們必須手動糾正,將Cat.prototype對象的constructor值改為Ca t。這就是第二行的意思,這顯然會導致繼承鏈的紊亂(cat1明明是用構造函數Cat生成的),因此我們必須手動糾正,將Cat.prototype對 象的constructor值改為Cat。這就是第二行的意思。   o.prototype = {}; 那么,下一步必然是為新的prototype對象加上constructor屬性,并將這個屬性指回原來的構造函數。   o.prototype.constructor = o; ~~~ <br/> >[success] ## 三、 直接繼承prototype ~~~ 第三種方法是對第二種方法的改進。由于Animal對象中,不變的屬性都可以直接寫入Animal.prototype。所以,我們也可以讓Cat()跳過 Animal(),直接繼承Animal.prototype。 現在,我們先將Animal對象改寫:   function Animal(){ }   Animal.prototype.species = "動物"; 然后,將Cat的prototype對象,然后指向Animal的prototype對象,這樣就完成了繼承。   Cat.prototype = Animal.prototype;   Cat.prototype.constructor = Cat;   var cat1 = new Cat("大毛","黃色");   alert(cat1.species); // 動物 與前一種方法相比,這樣做的優點是效率比較高(不用執行和建立Animal的實例了),比較省內存。缺點是 Cat.prototype和Animal.prototype現在指向了同一個對象,那么任何對Cat.prototype的修改,都會反映到Animal.prototype。 所以,上面這一段代碼其實是有問題的。請看第二行   Cat.prototype.constructor = Cat; 這一句實際上把Animal.prototype對象的constructor屬性也改掉了! ~~~ <br/> >[success] ## 四、 利用空對象作為中介 ~~~ 由于"直接繼承prototype"存在上述的缺點,所以就有第四種方法,利用一個空對象作為中介。   var F = function(){};   F.prototype = Animal.prototype;   Cat.prototype = new F();   Cat.prototype.constructor = Cat; F是空對象,所以幾乎不占內存。這時,修改Cat的prototype對象,就不會影響到Animal的prototype對象。   alert(Animal.prototype.constructor); // Animal 我們將上面的方法,封裝成一個函數,便于使用。 // Child繼承者 , Parent父級   function extend(Child, Parent) { var F = function(){}; F.prototype = Parent.prototype; Child.prototype = new F(); Child.prototype.constructor = Child; Child.uber = Parent.prototype;   } 使用的時候,方法如下:   extend(Cat,Animal);   var cat1 = new Cat("大毛","黃色");   alert(cat1.species); // 動物 這個extend函數,就是YUI庫如何實現繼承的方法。 另外,說明一點,函數體最后一行 Child.uber = Parent.prototype; 意思是為子對象設一個uber屬性,這個屬性直接指向父對象的prototype屬性。(uber是一個德語詞,意思是"向上"、"上一層"。)這等于在 子對象上打開一條通道,可以直接調用父對象的方法。這一行放在這里,只是為了實現繼承的完備性,純屬備用性質。 ~~~ <br/> >[success] ## 五、 拷貝繼承 ~~~ 上面是采用prototype對象,實現繼承。我們也可以換一種思路,純粹采用"拷貝"方法實現繼承。簡單說,如果把父對象的所有屬性和方法, 拷貝進子對象,不也能夠實現繼承嗎?這樣我們就有了第五種方法。首先,還是把Animal的所有不變屬性,都放到它的prototype對象上。   function Animal(){}   Animal.prototype.species = "動物"; 然后,再寫一個函數,實現屬性拷貝的目的。   function extend2(Child, Parent) {     var p = Parent.prototype;     var c = Child.prototype;     for (var i in p) {       c\[i\] = p\[i\];       }     c.uber = p;   } 這個函數的作用,就是將父對象的prototype對象中的屬性,一一拷貝給Child對象的prototype對象。 使用的時候,這樣寫:   extend2(Cat, Animal);   var cat1 = new Cat("大毛","黃色");   alert(cat1.species); // 動物 ~~~
                  <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>

                              哎呀哎呀视频在线观看