国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

JavaScript繼承學(xué)習(xí)筆記【新手必看】

2019-11-20 10:06:46
字體:
供稿:網(wǎng)友

JavaScript作為一個面向?qū)ο笳Z言(JS是基于對象的),可以實現(xiàn)繼承是必不可少的,但是由于本身并沒有類的概念,所以不會像真正的面向?qū)ο缶幊陶Z言通過類實現(xiàn)繼承,但可以通過其他方法實現(xiàn)繼承。實現(xiàn)繼承的方法很多,下面就只是其中的幾種。

一. 原型鏈繼承

function Person() {  //被繼承的函數(shù)叫做超類型(父類,基類)      this.name='mumu';      this.age='18';    }        Person.prototype.name='susu';//當(dāng)屬性名相同時需就近原則,先在實例里面查找,沒找到再到原型里找           function Worker(){ //繼承的函數(shù)叫做子類型(子類,派生類)      this.job='student';    }    Worker.prototype=new Person();//通過原型鏈繼承,超類型實例化后的對象實例,賦值給子類的原型屬性    var p2=new Worker();     console.log(p2.name);    console.log(p2 instanceof Object);//ture 所有的構(gòu)造函數(shù)都繼承自O(shè)bject

以上實現(xiàn)繼承關(guān)鍵在于:Worker.prototype=new Person();  將Worker的原型成為Person的一個實例,通過原型鏈繼承。

注意:在使用原型鏈實現(xiàn)繼承時,不能使用對象字面量創(chuàng)建原型方法,因為這樣會中斷關(guān)系而重寫原型鏈。

原型鏈繼承問題:

1.出現(xiàn)引用共享問題,他們還是共用一個空間,子類會影響父類

function Person() {        this.bodys=['eye','foot'];    }        function Worker(){     }    Worker.prototype=new Person();    var p1=new Worker();    p1.bodys.push('hand');    var p2=new Worker();     console.log(p1.bodys);    console.log(p2.bodys);

2.在創(chuàng)建子類型的實例時,不能像超類型的構(gòu)造函數(shù)中傳遞參數(shù)。

那么如何解決原型鏈的兩個問題呢?那就繼續(xù)看下面的繼承方式吧~

二. 借用構(gòu)造函數(shù)繼承(也叫對象冒充,偽造對象或經(jīng)典繼承)

function Person(name,age){    this.name=name;    this.age=age;    this.bodys=['eye','foot'];  }  Person.prototype.showName=function(){    console.log(this.name);  }  function Worker(name,age,job){    Person.call(this,name,age);    this.job=job;//子類添加屬性  }  var p1=new Worker('mumu','18','學(xué)生');   p1.bodys.push('hand') ;  var p2=new Worker();  console.log(p1.name);  console.log(p2.bodys);  console.log(p1.showName());

簡單分析下以上使用借用構(gòu)造函數(shù)的原理:Person.call(this,name,age);這句代碼調(diào)用父級構(gòu)造函數(shù),繼承父級屬性,使用call方法調(diào)用Person構(gòu)造函數(shù)改變函數(shù)執(zhí)行時候的this,  這里的this-> new出來的一個Worker對象  構(gòu)造函數(shù)偽裝方法:把Worker傳給上面的Person。

當(dāng)引用類型放在構(gòu)造函數(shù)里面的時候就不會被共享,所以p2不受影響。

這里借用構(gòu)造函數(shù)繼承方式就解決了原型鏈不能傳遞參數(shù)以及引用類型共享的問題。

小知識:call()和apply()方法可以改變函數(shù)執(zhí)行的作用域, 簡言之就是改變函數(shù)中this指向的內(nèi)容。

call()和apply()都接受兩個參數(shù):第一個是在其中運行函數(shù)的作用域,另一個是傳遞的參數(shù)。

call和apply的區(qū)別就是參數(shù)的不同.
call中的參數(shù)必須是一個個枚舉出來的.
apply中的參數(shù)必須是數(shù)組或者是arguments對象

那么問題來了:為什么p1.showName()結(jié)果是錯誤的呢?----因為借用構(gòu)造函數(shù)繼承方式只能繼承構(gòu)造函數(shù)里的屬性和方法。這里也就發(fā)現(xiàn)了借用構(gòu)造函數(shù)的一個問題。

注意:由于把方法都放在構(gòu)造函數(shù)里,每次我們實例化就會分配內(nèi)存空間給它造成資源的浪費,所以一般我們都是把方法放在原型里,屬性放在構(gòu)造函數(shù)里。


借用構(gòu)造函數(shù)繼承問題:

因為借用構(gòu)造函數(shù)只能繼承構(gòu)造函數(shù)里的屬性和方法,在超類型的原型中定義的方法對子類而言是不可見的,所以就相當(dāng)于沒有了原型。結(jié)果所有的方法都只能在構(gòu)造函數(shù)里定義,因此就沒有函數(shù)復(fù)用了。

那么如何解決借用構(gòu)造函數(shù)所產(chǎn)生的問題呢?那就要看下面這種繼承方式了

三. 組合繼承(偽經(jīng)典繼承)

function Person(name,age){    this.name=name;    this.age=age;  }  Person.prototype.showName=function(){    console.log(this.name);  }  function Worker(name,age,job){    Person.call(this,name,age);//借用構(gòu)造函數(shù)    this.job=job;  }    Worker.prototype=new Person();//原型鏈繼承  var p1=new Worker('mumu','18','學(xué)生');   console.log(p1.age);  p1.showName();

組合繼承:將原型鏈與借用構(gòu)造函數(shù)結(jié)合。

思路:通過使用原型鏈實現(xiàn)原型上的屬性和方法繼承,借用構(gòu)造函數(shù)實現(xiàn)實例屬性的繼承

以上的例子Person.call(this,name,age);借用構(gòu)造函數(shù)繼承了屬性

Worker.prototype=new Person();原型鏈繼承了方法 , 避免了兩者的缺點,融合了它們的優(yōu)點,成為最常用的繼承模式。

組合繼承的問題:

調(diào)用兩次超類型構(gòu)造函數(shù),一次是在創(chuàng)建子類型原型時,另一次是在子類型的構(gòu)造函數(shù)內(nèi)部。

要解決這個問題就要用到寄生組合式繼承方式了。

四. 原型式繼承

function object(proto) {    function F() {}    F.prototype = proto;    return new F();  }  var person = {    name: 'mumu',    friends: ['xiaxia', 'susu']  };  var anotherPerson = object(person);  anotherPerson.friends.push('wen');  var yetAnotherPerson = object(person);  anotherPerson.friends.push('tian');  console.log(person.friends);//["xiaxia", "susu", "wen", "tian"]console.log(anotherPerson.__proto__)//Object {name: "mumu", friends: Array[4]}

簡單分析下:function object(proto)是一個臨時中轉(zhuǎn)函數(shù),里面的參數(shù)proto表示將要傳遞進(jìn)入的一個對象,F(xiàn)()構(gòu)造函數(shù)是臨時新建的對象,用來存儲傳遞過來的對象,F(xiàn).prototype = proto;將對象實例賦值給F構(gòu)造函數(shù)的原型對象,最后返回傳遞過來的對象的對象實例。原型式繼承還是會共享引用類型的屬性。

五. 寄生式繼承

//臨時中轉(zhuǎn)函數(shù)  function object(proto) {    function F() {}    F.prototype = proto;    return new F();  }  //寄生函數(shù)  function create(proto){    var f=object(proto);    f.love=function(){      return this.name;    }    return f;  }  var person = {    name: 'mumu',    friends: ['xiaxia', 'susu']  };  var anotherPerson = create(person);  console.log(anotherPerson.love());寄生組合式繼承

六. 寄生組合式繼承

function object(proto) {    function F() {}    F.prototype = proto;    return new F();  }  //寄生函數(shù)  function create(Person,Worker){    var f=object(Person.prototype);//創(chuàng)建對象    f.constructor=Worker;//調(diào)整原型構(gòu)造指針,增強(qiáng)對象    Worker.prototype=f;//指定對象  }    function Person(name,age){    this.name=name;    this.age=age;  }  Person.prototype.showName=function(){    console.log(this.name);  }  function Worker(name,age,job){    Person.call(this,name,age);    this.job=job;  }    create(Person,Worker);//寄生組合式繼承  var p1=new Person('mumu','18','學(xué)生');p1.showName();

這種方法也是現(xiàn)在實現(xiàn)繼承方法中最完美的,也是最理想的。

以上這篇JavaScript繼承學(xué)習(xí)筆記【新手必看】就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持武林網(wǎng)。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 高唐县| 湖口县| 咸宁市| 松桃| 南和县| 湖口县| 龙里县| 盈江县| 巴南区| 丰都县| 山阳县| 古浪县| 元阳县| 古蔺县| 饶河县| 汤原县| 酒泉市| 甘谷县| 富锦市| 白银市| 恩平市| 苏尼特左旗| 文登市| 石林| 奈曼旗| 龙口市| 新乐市| 麻城市| 肥乡县| 通榆县| 兖州市| 翁牛特旗| 万安县| 新巴尔虎右旗| 神农架林区| 两当县| 隆化县| 浦县| 宜阳县| 台湾省| 松潘县|