日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

[js高手之路]从原型链开始图解继承到组合继承的产生

發(fā)布時(shí)間:2023/12/20 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [js高手之路]从原型链开始图解继承到组合继承的产生 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

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

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

1 function Person(){ 2 this.userName = 'ghostwu'; 3 } 4 Person.prototype.showUserName = function(){ 5 return this.userName; 6 } 7 function Teacher (){} 8 Teacher.prototype = new Person(); 9 10 var oT = new Teacher(); 11 console.log( oT.userName ); //ghostwu 12 console.log( oT.showUserName() ); //ghostwu

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

如果你不會(huì)畫這個(gè)圖,你需要去看下我的這篇文章:[js高手之路]一步步圖解javascript的原型(prototype)對(duì)象,原型鏈

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

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

所以停止查找,輸出ghostwu.

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

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

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

1 function Person(){ 2 this.userName = 'ghostwu'; 3 } 4 Person.prototype.showUserName = function(){ 5 return 'Person::showUserName方法'; 6 } 7 function Teacher (){} 8 Teacher.prototype = Person.prototype; 9 10 var oT = new Teacher(); 11 console.log( oT.showUserName() ); //ghostwu 12 console.log( oT.userName ); //undefined, 沒(méi)有繼承到父類的userName

因?yàn)門eacher.prototype被Person.protoype替換了( 第8行代碼 ),所以,Teacher的prototype屬性就直接指向了Person.prototype. 所以獲取不到Person實(shí)例的屬性

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

還是通過(guò)instanceof和isPrototypeOf判斷

1 function Person(){ 2 this.userName = 'ghostwu'; 3 } 4 Person.prototype.showUserName = function(){ 5 return this.userName; 6 } 7 function Teacher (){} 8 Teacher.prototype = new Person(); 9 10 var oT = new Teacher(); 11 console.log( oT instanceof Teacher ); //true 12 console.log( oT instanceof Person ); //true 13 console.log( oT instanceof Object ); //true 14 console.log( Teacher.prototype.isPrototypeOf( oT ) ); //true 15 console.log( Person.prototype.isPrototypeOf( oT ) ); //true 16 console.log( Object.prototype.isPrototypeOf( oT ) ); //true

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

1 function Person() {} 2 Person.prototype.showUserName = function () { 3 console.log('Person::showUserName'); 4 } 5 function Teacher() { } 6 Teacher.prototype = new Person(); 7 Teacher.prototype.showUserName = function(){ 8 console.log('Teacher::showUserName'); 9 } 10 Teacher.prototype.showAge = function(){ 11 console.log( 22 ); 12 } 13 var oT = new Teacher(); 14 oT.showUserName(); //Teacher::showUserName 15 oT.showAge(); //22

五、重寫原型對(duì)象之后,其實(shí)就是把構(gòu)造函數(shù)的原型屬性(prototype)的指向發(fā)生了改變

構(gòu)造函數(shù)的原型屬性(prototype)的指向發(fā)生了改變,會(huì)把原本的繼承關(guān)系覆蓋(切斷)

1 function Person() {} 2 Person.prototype.showUserName = function () { 3 console.log('Person::showUserName'); 4 } 5 function Teacher() {} 6 Teacher.prototype = new Person(); 7 Teacher.prototype = { 8 showAge : function(){ 9 console.log( 22 ); 10 } 11 } 12 var oT = new Teacher(); 13 oT.showAge(); //22 14 oT.showUserName();

上例,第7行,Teacher.prototype重寫了Teacher的原型對(duì)象(prototype),原來(lái)第6行的Teacher構(gòu)造函數(shù)的prototype屬性指向new Person()的關(guān)系切斷了

所以在第14行,oT.showUserName() 就會(huì)發(fā)生調(diào)用錯(cuò)誤,因?yàn)門eacher構(gòu)造函數(shù)上的prototype屬性不再指向父類(Person)的實(shí)例,繼承關(guān)系被破壞了.

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

1 function Person(){ 2 this.skills = [ 'php', 'javascript' ]; 3 } 4 function Teacher (){} 5 Teacher.prototype = new Person(); 6 7 var oT1 = new Teacher(); 8 var oT2 = new Teacher(); 9 oT1.skills.push( 'linux' ); 10 console.log( oT2.skills ); //php, java, linux

oT1的skills添加了一項(xiàng)linux數(shù)據(jù),其他的實(shí)例都能訪問(wèn)到,因?yàn)槠渌麑?shí)例中共享了skills數(shù)據(jù),skills是一個(gè)引用類型

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

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

1 function Person( uName ){ 2 this.skills = [ 'php', 'javascript' ]; 3 this.userName = uName; 4 } 5 Person.prototype.showUserName = function(){ 6 return this.userName; 7 } 8 function Teacher ( uName ){ 9 Person.call( this, uName ); 10 } 11 var oT1 = new Teacher(); 12 oT1.skills.push( 'linux' ); 13 var oT2 = new Teacher(); 14 console.log( oT2.skills ); //php,javascript 15 console.log( oT2.showUserName() );

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

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

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

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

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

Teacher.prototype = new Person();

有些人說(shuō),小括號(hào)后面可以跟參數(shù)啊,沒(méi)錯(cuò),但是只要跟了參數(shù),子類所有的實(shí)例屬性,都是跟這個(gè)一樣,說(shuō)白了,還是傳遞不了參數(shù)

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

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

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

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

1 function Person( uName ){ 2 this.skills = [ 'php', 'javascript' ]; 3 this.userName = uName; 4 } 5 Person.prototype.showUserName = function(){ 6 return this.userName; 7 } 8 function Teacher ( uName ){ 9 Person.call( this, uName ); 10 } 11 Teacher.prototype = new Person(); 12 13 var oT1 = new Teacher( 'ghostwu' ); 14 oT1.skills.push( 'linux' ); 15 var oT2 = new Teacher( 'ghostwu' ); 16 console.log( oT2.skills ); //php,javascript 17 console.log( oT2.showUserName() ); //ghostwu

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

總結(jié)

以上是生活随笔為你收集整理的[js高手之路]从原型链开始图解继承到组合继承的产生的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。