面向面試編程——javascript繼承的6種方法

來源:互聯網
上載者:User

標籤:pre   UI   自訂   原型   修改   efi   friends   屬性   對象   

javascript繼承的6種方法

1,原型鏈繼承2,借用建構函式繼承3,組合繼承(原型+借用構造)4,原型式繼承5,寄生式繼承6,寄生組合式繼承

1.原型鏈繼承.

<script type="text/javascript">    function Person(name,sex)    {        this.name=name;        this.sex=sex;        this.friends=[‘李四‘];        this.getName=function(){            alert(this.name);        }    }   Person.prototype.id=1;    function Boy(age)    {        this.age=age;        this.getAge=function(){            alert(this.age);        }    }    //繼承    Boy.prototype=new Person("張三","男");    var boy=new Boy(16);       alert(boy.name);              //張三    boy.getAge();               //16    alert(boy.id);                 //1    //屬性共用問題    console.log(boy.friends);            //李四    var boy2=new Boy(17);    boy2.friends.push(‘王五‘);  //修改boy2的friends屬性的同時也影響了boy的屬性    console.log(boy.friends);            //李四 王五    //驗證能否使用instanceof 和 isPrototypeof    console.log(boy instanceof Person);                 //true    console.log(Person.prototype.isPrototypeOf(boy));   //true</script>

 

特點:既繼承了父類的模板,又繼承了父類的原型對象。

缺點:只能在父類設定一些參數,子類不能靈活傳參,不符合物件導向的思想,包含參考型別值的屬性始終都會共用相應的值。

 

2.借用建構函式繼承

<script type="text/javascript">      //父類    function Person(name,sex)    {        this.name=name;        this.sex=sex;        this.friends=[‘李四‘];    }    Person.prototype.id=1;    //子類    function Boy(name,sex,age)    {        //借用        Person.call(this,name,age);        this.age=age;        this.getAge=function(){            alert(this.age);        }    }    var boy=new Boy("張三","男",16);    alert(boy.name);  //張三    boy.getAge();        //16    alert(boy.id);  //undefined  沒有繼承父類的原型對象    //屬性共用問題 ————不會有共用      //驗證能否使用instanceof 和 isPrototypeof    console.log(boy instanceof Person);                 //false    console.log(Person.prototype.isPrototypeOf(boy));   //false</script>

 

 

特點:只繼承了父類的模板,不繼承父類的原型對象。

缺點:方法都在建構函式中定義,不能做到函數複用。

3.組合繼承(原型+借用構造)最常用的繼承模式

<script type="text/javascript">     //父類    function Person(name,sex)    {        this.name=name;        this.sex=sex;            }    Person.prototype.id=1;    //子類    function Boy(name,sex,age)    {        //借用建構函式  繼承父類的模板        Person.call(this,name,age);        this.age=age;        this.getAge=function(){            alert(this.age);        }    }        //不傳遞參數,繼承父類的模板,繼承父類的原型對象 id     Boy.prototype=new Person();    var boy=new Boy("張三","男",16);    alert(boy.name);  //張三    boy.getAge();        //16    alert(boy.id);  //1    //屬性共用問題 ————除了父類的原型對象,不會有共用      //驗證能否使用instanceof 和 isPrototypeof    console.log(boy instanceof Person);                 //true    console.log(Person.prototype.isPrototypeOf(boy));   //true</script>

 

特點:既繼承了父類的模板,又繼承了父類的原型對象。

缺點:做了3件事,繼承了父類兩次模板,繼承了一次原型對象

原型式繼承解決了這個問題

4.原型式繼承

<script type="text/javascript">   var person={    name:‘張三‘,    sex:‘男‘,    friends:[‘李四‘]    }    function object(obj)    {        function F(){}   //建立一個空的建構函式        F.prototype=obj;  //將傳入的對象作為這個建構函式的原型        return new F();   //返回一個新執行個體  對傳入的對象進行了一次淺複製    }    var boy=object(person);    //ECMAScript 5 新增了Object.create()方法 與本例 object 方法行為相同    //可改為 Object.create(person);    alert(boy.name);  //張三    //但是原型式同樣存在屬性共用的問題    //例如:    var girl=object(person);    girl.friends.push(‘王五‘);    alert(boy.friends); //李四 王五    alert(girl.friends);//李四 王五    //修改girl中的friends屬性  boy 也會受到影響         //無法使用 instanceof 和 isPrototypeof   </script>

 

創造的目的是基於已有的對象建立新的對象,同時還不必因此建立自訂類型。

包含參考型別值的屬性始終都會共用相應的值,就像使用原型模式一樣。

 

5.寄生式繼承

<script type="text/javascript">    function object(obj)    {        function F(){}   //建立一個空的建構函式        F.prototype=obj;  //將傳入的對象作為這個建構函式的原型        return new F();   //返回一個新執行個體  對傳入的對象進行了一次淺複製    }    function Person(person)    {        var clone=object(person);        clone.getSex=function(){            alert(this.sex);        }        return clone;    }    var person={        name:‘張三‘,        sex:‘男‘,        friends:[‘李四‘]    }    var boy=Person(person);    boy.getSex();         //男    //屬性共用問題————因為傳入同一個執行個體,所以存在共用問題      var boy2=Person(person);      boy2.friends.push(‘王五‘);        alert(boy.friends);     //李四  王五        //驗證能否使用instanceof 和 isPrototypeof    console.log(boy instanceof Person);                 //false    console.log(Person.prototype.isPrototypeOf(boy));   //false</script>

 

與建構函式模式類似,不能做到函數複用會降低效率。

6.寄生組合式繼承

<script type="text/javascript">        function object(o)    {        function F(){}        console.log(o);        F.prototype=o;        return new F();    }    function extend(subType,superType)    {        var prototype=object(superType.prototype);  //建立父類的一個副本        prototype.constructor=subType;                //為建立的副本添加失去預設的建構函式        subType.prototype=prototype;                //將新建立的對象賦值給子類的原型    }    function Person(name)    {        this.name=name;        this.friends=[‘李四‘];    }    function Boy(name,sex)    {        Person.call(this,name);             //借用建構函式  繼承父類的模板        this.sex=sex;    }    extend(Boy,Person);  //繼承    var boy=new Boy(‘張三‘,‘男‘);    alert(boy.name);     //張三    //屬性共用問題————不會存在共用問題      var boy2=new Boy(‘張三‘,‘男‘);      boy2.friends.push(‘王五‘);        alert(boy.friends);     //李四    //驗證能否使用instanceof 和 isPrototypeof    console.log(boy instanceof Person);                 //false    console.log(Person.prototype.isPrototypeOf(boy));   //false</script>

 

寄生式組合繼承解決了組合繼承會調用兩次父類建構函式,子類最終會包含父類的全部執行個體屬性,父類的屬性不是必須的,子類的屬性會覆蓋父類的屬性。

寄生式組合繼承只調用一次父類建構函式,原型鏈能保持不變,因此還能夠正常使用instanceof和isPrototypeOf(),YUI的extend方法就使用的是寄生組合繼承,是實現基於類型繼承的最有效方式。

面向面試編程——javascript繼承的6種方法

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.