最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

[js高手之路]從原型鏈開始圖解繼承到組合繼承的產(chǎn)生詳解

 更新時間:2017年08月28日 08:18:37   作者:ghostwu  
下面小編就為大家?guī)硪黄猍js高手之路]從原型鏈開始圖解繼承到組合繼承的產(chǎn)生詳解。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

于javascript原型鏈的層層遞進查找規(guī)則,以及原型對象(prototype)的共享特性,實現(xiàn)繼承是非常簡單的事情

一、把父類的實例對象賦給子類的原型對象(prototype),可以實現(xiàn)繼承

function Person(){
 this.userName = 'ghostwu';
 }
 Person.prototype.showUserName = function(){
 return this.userName;
 }
 function Teacher (){}
 Teacher.prototype = new Person();

 var oT = new Teacher(); 
 console.log( oT.userName ); //ghostwu
 console.log( oT.showUserName() ); //ghostwu

通過把父類(Person)的一個實例賦給子類Teacher的原型對象,就可以實現(xiàn)繼承,子類的實例就可以訪問到父類的屬性和方法

如果你不會畫這個圖,你需要去看下我的這篇文章:

[js高手之路]一步步圖解javascript的原型(prototype)對象,原型鏈

第11行,執(zhí)行oT.userName, 首先去oT對象上查找,很明顯oT對象上沒有任何屬性,所以就順著oT的隱式原型__proto__的指向查找到Teacher.prototype,

發(fā)現(xiàn)還是沒有userName這個屬性,繼續(xù)沿著Teacher.prototype.__proto__向上查找,找到了new Person() 這個實例上面有個userName,值為ghostwu

所以停止查找,輸出ghostwu.

第12行,執(zhí)行oT.showUserName前面的過程同上,但是在new Person()這個實例上還是沒有查找到showUserName這個方法,繼續(xù)沿著new Person()的

隱式原型__proto__的指向( Person.prototype )查找,在Person.prototype上找到了showUserName這個方法,停止查找,輸出ghostwu.

二、把父類的原型對象(prototype)賦給子類的原型對象(prototype),可以繼承到父類的方法,但是繼承不到父類的屬性

function Person(){
 this.userName = 'ghostwu';
 }
 Person.prototype.showUserName = function(){
 return 'Person::showUserName方法';
 }
 function Teacher (){}
 Teacher.prototype = Person.prototype;

 var oT = new Teacher(); 
 console.log( oT.showUserName() ); //ghostwu
 console.log( oT.userName ); //undefined, 沒有繼承到父類的userName

因為Teacher.prototype的隱式原型(__proto__)只指向Person.prototype,所以獲取不到Person實例的屬性

三、發(fā)生繼承關(guān)系后,實例與構(gòu)造函數(shù)(類)的關(guān)系判斷

還是通過instanceof和isPrototypeOf判斷

function Person(){
 this.userName = 'ghostwu';
 }
 Person.prototype.showUserName = function(){
 return this.userName;
 }
 function Teacher (){}
 Teacher.prototype = new Person();
 
 var oT = new Teacher();
 console.log( oT instanceof Teacher ); //true
 console.log( oT instanceof Person ); //true
 console.log( oT instanceof Object ); //true
 console.log( Teacher.prototype.isPrototypeOf( oT ) ); //true
 console.log( Person.prototype.isPrototypeOf( oT ) ); //true
 console.log( Object.prototype.isPrototypeOf( oT ) ); //true

四,父類存在的方法和屬性,子類可以覆蓋(重寫),子類沒有的方法和屬性,可以擴展

function Person() {}
 Person.prototype.showUserName = function () {
 console.log('Person::showUserName');
 }
 function Teacher() { }
 Teacher.prototype = new Person();
 Teacher.prototype.showUserName = function(){
 console.log('Teacher::showUserName');
 }
 Teacher.prototype.showAge = function(){
 console.log( 22 );
 }
 var oT = new Teacher();
 oT.showUserName(); //Teacher::showUserName
 oT.showAge(); //22

五、重寫原型對象之后,其實就是把原型對象的__proto__的指向發(fā)生了改變

原型對象prototype的__proto__的指向發(fā)生了改變,會把原本的繼承關(guān)系覆蓋(切斷)

function Person() {}
 Person.prototype.showUserName = function () {
 console.log('Person::showUserName');
 }
 function Teacher() {}
 Teacher.prototype = new Person();
 Teacher.prototype = {
 showAge : function(){
 console.log( 22 );
 }
 }
 var oT = new Teacher();
 oT.showAge(); //22
 oT.showUserName();

上例,第7行,Teacher.prototype重寫了Teacher的原型對象(prototype),原來第6行的原型對象的隱式原型(__proto__)指向就沒有作用了

所以在第14行,oT.showUserName() 就會發(fā)生調(diào)用錯誤,因為Teacher的原型對象(prototype)的隱式原型(__proto__)不再指向父類(Person)的實例,繼承關(guān)系被破壞了.

六、在繼承過程中,小心處理實例的屬性上引用類型的數(shù)據(jù)

function Person(){
 this.skills = [ 'php', 'javascript' ];
 }
 function Teacher (){}
 Teacher.prototype = new Person();

 var oT1 = new Teacher();
 var oT2 = new Teacher();
 oT1.skills.push( 'linux' );
 console.log( oT2.skills ); //php, java, linux

oT1的skills添加了一項linux數(shù)據(jù),其他的實例都能訪問到,因為其他實例中共享了skills數(shù)據(jù),skills是一個引用類型

七、借用構(gòu)造函數(shù)

為了消除引用類型影響不同的實例,可以借用構(gòu)造函數(shù),把引用類型的數(shù)據(jù)復(fù)制到每個對象上,就不會相互影響了

function Person( uName ){
 this.skills = [ 'php', 'javascript' ];
 this.userName = uName;
 }
 Person.prototype.showUserName = function(){
 return this.userName;
 }
 function Teacher ( uName ){
 Person.call( this, uName );
 }
 var oT1 = new Teacher();
 oT1.skills.push( 'linux' );
 var oT2 = new Teacher();
 console.log( oT2.skills ); //php,javascript
 console.log( oT2.showUserName() );

雖然oT1.skills添加了一項Linux,但是不會影響oT2.skills的數(shù)據(jù),通過子類構(gòu)造函數(shù)中call的方式,去借用父類的構(gòu)造函數(shù),把父類的屬性復(fù)制過來,而且還能

傳遞參數(shù),如第8行,但是第15行,方法調(diào)用錯誤,因為在構(gòu)造中只復(fù)制了屬性,不會復(fù)制到父類原型對象上的方法

八、組合繼承(原型對象+借用構(gòu)造函數(shù))

經(jīng)過以上的分析, 單一的原型繼承的缺點有:

1、不能傳遞參數(shù),如,

Teacher.prototype = new Person();
有些人說,小括號后面可以跟參數(shù)啊,沒錯,但是只要跟了參數(shù),子類所有的實例屬性,都是跟這個一樣,說白了,還是傳遞不了參數(shù)

2、把引用類型放在原型對象上,會在不同實例上產(chǎn)生相互影響

單一的借用構(gòu)造函數(shù)的缺點:

1、不能復(fù)制到父類的方法

剛好原型對象方式的缺點,借用構(gòu)造函數(shù)可以彌補,借用構(gòu)造函數(shù)的缺點,原型對象方式可以彌補,于是,就產(chǎn)生了一種組合繼承方法:

function Person( uName ){
 this.skills = [ 'php', 'javascript' ];
 this.userName = uName;
 }
 Person.prototype.showUserName = function(){
 return this.userName;
 }
 function Teacher ( uName ){
 Person.call( this, uName );
 }
 Teacher.prototype = new Person();

 var oT1 = new Teacher( 'ghostwu' );
 oT1.skills.push( 'linux' );
 var oT2 = new Teacher( 'ghostwu' );
 console.log( oT2.skills ); //php,javascript
 console.log( oT2.showUserName() ); //ghostwu

子類實例oT2的skills不會受到oT1的影響,子類的實例也能調(diào)用到父類的方法。

以上這篇[js高手之路]從原型鏈開始圖解繼承到組合繼承的產(chǎn)生詳解就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Three.js+React實現(xiàn)3D開放世界小游戲

    Three.js+React實現(xiàn)3D開放世界小游戲

    本文使用?Three.js?+?React?+?CANNON?技術(shù)棧,實現(xiàn)通過滑動屏幕控制模型在3D世界里運動的?Low?Poly?低多邊形風(fēng)格小游戲,感興趣的可以了解一下
    2022-04-04
  • javascript 處理null及null值示例

    javascript 處理null及null值示例

    這篇文章以示例的方式為大家介紹下javascript 如何處理null及'null'值,需要的朋友可以參考下
    2014-06-06
  • javascript實現(xiàn)簡單計算器效果【推薦】

    javascript實現(xiàn)簡單計算器效果【推薦】

    下面小編就為大家?guī)硪黄猨avascript實現(xiàn)簡單計算器效果【推薦】。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考
    2016-04-04
  • 簡介BootStrap model彈出框的使用

    簡介BootStrap model彈出框的使用

    這篇文章主要介紹了BootStrap model彈出框的使用,介紹的非常詳細(xì),具有參考借鑒價值,感興趣的朋友一起學(xué)習(xí)吧
    2016-04-04
  • JS 音頻可視化插件Wavesurfer.js的使用教程

    JS 音頻可視化插件Wavesurfer.js的使用教程

    Wavesurfer.js是一款基于HTML5 canvas和Web Audio的音頻播放器插件,本文主要記錄它及其視覺效果插件Regions插件的使用方法,感興趣的朋友跟隨小編一起看看吧
    2018-10-10
  • javascript獲取鼠標(biāo)位置部分的實例代碼(兼容IE,FF)

    javascript獲取鼠標(biāo)位置部分的實例代碼(兼容IE,FF)

    這篇文章介紹了javascript獲取鼠標(biāo)位置部分的實例代碼,有需要的朋友可以參考一下
    2013-08-08
  • layer 刷新某個頁面的實現(xiàn)方法

    layer 刷新某個頁面的實現(xiàn)方法

    今天小編就為大家分享一篇layer 刷新某個頁面的實現(xiàn)方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-09-09
  • js前端面試之同步與異步問題詳解

    js前端面試之同步與異步問題詳解

    這篇文章主要給大家介紹了關(guān)于js前端面試之同步與異步問題的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用js具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • 原生js實現(xiàn)購物車

    原生js實現(xiàn)購物車

    這篇文章主要為大家詳細(xì)介紹了原生js實現(xiàn)購物車,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-09-09
  • JS 網(wǎng)頁彩蛋 實現(xiàn)代碼

    JS 網(wǎng)頁彩蛋 實現(xiàn)代碼

    顯示一定時間后消失,刷新之后清空變量值,重新開始記錄鍵值。 程序的原理就是檢測按鍵的鍵值,當(dāng)達(dá)到預(yù)定條件時執(zhí)行規(guī)定的函數(shù)。
    2009-09-09

最新評論

华容县| 新余市| 克拉玛依市| 咸丰县| 汨罗市| 柘城县| 赤峰市| 渭南市| 甘洛县| 沧州市| 竹山县| 康定县| 宁武县| 炎陵县| 桑日县| 承德市| 齐河县| 丹寨县| 泉州市| 新乡市| 长泰县| 泰安市| 久治县| 黄山市| 梨树县| 上杭县| 普陀区| 河津市| 山丹县| 牡丹江市| 天台县| 高安市| 左云县| 西城区| 仁布县| 通化市| 宣威市| 平谷区| 威海市| 永登县| 锦州市|