日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

JavaScript中繼承原理與用法實例入門

瀏覽:155日期:2023-10-29 08:36:55

本文實例講述了JavaScript中繼承原理與用法。分享給大家供大家參考,具體如下:

正統的面相對象的語言都會提供extend之類的方法用于出來類的繼承,但Javascript并不提供extend方法,在Javascript中使用繼承需要用點技巧。

Javascript中的實例的屬性和行為是由構造函數和原型兩部分組成的,我們定義兩個類:Person和zhangsan,它們在內存中的表現如下圖1:JavaScript中繼承原理與用法實例入門如果想讓Zhangsan繼承Person,那么我們需要把Person構造函數和原型中的屬性和行為全部傳給Zhangsan的構造函數和原型,如下圖2所示:JavaScript中繼承原理與用法實例入門

Are you Ok?了解了繼承的思路后,那么我們一步步完成Person和Zhangsan的繼承功能。首先,我們需要定義Person類,如下代碼:[代碼1]

// 定義Person類function Person (name){ this.name = name; this.type = '人';}Person.prototype={ say : function(){ console.info('我是一個'+ this.type +',我的名字叫' + this.name); }} //定義Zhangsan類function Zhangsan (name){}Zhangsan.prototype={ }

Zhangsan雖然有自己特有的屬性和行為,但它大部分屬性和行為和Person相同,需要繼承自Person類。如前所述,JavaScript中繼承是要分別繼承構造函數和原型中的屬性和行為的。我們先讓Zhangsan繼承Person的構造函數中的行為和屬性,如下代碼:[代碼2]

// 定義Person類function Person (name){ this.name = name; this.type = '黃';}Person.prototype={ say : function(){ console.info('我是一個'+ this.type +'種人,我的名字叫' + this.name); }} //定義Zhangsan類function Zhangsan (name){ this.name = name; this.type = '黃';}Zhangsan.prototype={}//實例化Zhangsan對象var zs = new Zhangsan('張三');console.info(zs.type); // 黃

運行正常,但我們怎么沒看到繼承的“味道”呢?我們在Zhangsan的構造函數中將Person的屬性和行為復制了一份,與其說是繼承不如說是“真巧,這兩個類的構造函數除了函數名不同,其他地方都長得一樣”。她的缺點很明顯:如果Person類的構造函數有任何變動,我們也需要手動的同步修改Zhangsan類的構造函數,同樣一份代碼,我們復制了一份寫在了程序中 的不同地方,這違法了DRY原則,降低了代碼的可維護性。

好了,讓我們來改進它:[代碼3]

// 定義Person類function Person (name){ this.name = name; this.type = '黃';}Person.prototype={ say : function(){ console.info('我是一個'+ this.type +'種人,我的名字叫' + this.name); }} // 定義Zhangsan類function Zhangsan (name){ Person(name);}Zhangsan.prototype={}// 實例化Zhangsan對象var zs = new Zhangsan('張三');console.info(zs.type); // undefined

我們在Zhangsan的構造函數里調用Person()函數,希望它內部的ths.xxx可以在Zhangsan類的構造函數里執行一遍,但奇怪的是,出現“console.info(zs.type);”時,輸出的是undefined,這是怎么回事呢?

這和Person的調用方式有關。在JavaScript中,function有兩種不同的調用方法:

作為函數存在,直接用“()”調用,例如“function test(){}; test();”test被用作函數,直接被“()”符號調用。

作為類的構造函數存在,使用new調用,例如“function test(){}; new test();”test作為類的構造函數,通過new進行test類的實例化。這兩種方法的調用,function內部的this指向會有所不同---作為函數的function,其this指向的是window,而作為構造函數的function,其this指向的實例對象。

上面代碼中,Zhangsan類構造函數中的Person是通過函數方式調用的,它內部的this指向的是window對象,起效果等同于如下代碼:[代碼4]

// 定義Person類function Person (name){ this.name = name; this.type = '黃';}Person.prototype={ say : function(){ console.info('我是一個'+ this.type +'種人,我的名字叫' + this.name); }} // 定義Zhangsan類function Zhangsan (name){ window.name = name; window.type = '黃';}Zhangsan.prototype={}// 實例化Zhangsan對象var zs = new Zhangsan('張三');console.info(zs.type); // undefinedconsole.info(type); // 黃 (window.type可以省略寫成type)

如果想達到[代碼3]的效果,讓Person內部this指向Zhangsan類的實例,可以通過call或apply方法實現,如下:[代碼5]

// 定義Person類function Person (name){ this.name = name; this.type = '黃';}Person.prototype={ say : function(){ console.info('我是一個'+ this.type +'種人,我的名字叫' + this.name); }} // 定義Zhangsan類function Zhangsan (name){ Person.call(this,name);}Zhangsan.prototype={}// 實例化Zhangsan對象var zs = new Zhangsan('張三');console.info(zs.type); // 黃

構造函數的屬性和行為已經成功實現了繼承,接下來我們要實現原型中的屬性和行為的繼承。既然Zhangsan類需要和Person類原型中同樣的屬性和行為,那么能否將Person類的原型直接傳給Zhangsan類的原型,如下代碼:[代碼6]

// 定義Person類function Person (name){ this.name = name; this.type = '黃';}Person.prototype={ say : function(){ console.info('我是一個'+ this.type +'種人,我的名字叫' + this.name); }} // 定義Zhangsan類function Zhangsan (name){ Person.call(this,name);}Zhangsan.prototype = Person.prototype;// 實例化Zhangsan對象var zs = new Zhangsan('張三');// 我是一個黃種人,我的名字叫張三zs.say();

通過Person類的原型傳給Zhangsan類的原型,Zhangsan類成功獲得了say行為,但事情并不像想象中的那么簡單,如果我們要給Zhangsan類添加run行為呢?如下代碼:[代碼7:添加run行為]

// 定義Person類function Person (name){ this.name = name; this.type = '黃';}Person.prototype={ say : function(){ console.info('我是一個'+ this.type +'種人,我的名字叫' + this.name); }} // 定義Zhangsan類function Zhangsan (name){ Person.call(this,name);}Zhangsan.prototype = Person.prototype;Zhangsan.prototype.run = function(){ console.info('我100米短跑只要10秒!');}// 實例化Zhangsan對象var zs = new Zhangsan('張三');zs.say(); // 我是一個黃種人,我的名字叫張三zs.run(); //我100米短跑只要10秒!var zs2 = new Person('張三2');zs2.run(); //我100米短跑只要10秒!

我們只想給Zhangsan類添加run行為,為什么Person類也獲得了run行為了呢?這涉及傳值和傳址的兩個問題----在JavaScript中,賦值語句會用傳值和傳地址兩種不同的方式進行賦值,如果是數值型、不爾型、字符型等基本數據類型,在進行賦值時會將數據直接賦值一份,將賦值的那一份數據進行賦值,也就是通常所說的傳值;如果是數組、hash對象等復雜數據類型,在進行賦值時會直接用內存地址賦值,而不是將數據賦值一份,這就是傳址賦值,就是傳數據的映射地址。[代碼8:傳值與傳址]

var a=10; // 基本數據類型var b=a; // 將變量a保存的值賦值一份,傳給變量b,b和a各保存一份數據var c=[1,2,3]; // 復雜數據類型var d=c; // 將變量c指向的數據內存地址傳給變量d,c和d指向同一份數據b++;d.push(4);console.info(a); // 10console.info(b); // 11 變量b保存的數據更改不會影響到變量aconsole.info(c); // 1,2,3,4 變量c和d指向同一份數據,數據更改會相互影響console.info(d); // 1,2,3,4

在原生JavaScript中,選擇傳值還是傳地址是根據數據類型來自動判斷的,但傳地址有時候會給我們帶來意想不到的麻煩,所以我們需要對復雜數據類型的賦值進行控制,讓復雜數據類型也可以進行傳值。

最簡單的做法是遍歷數組或者Hash對象,將數組或者Hash對象這種復雜的數據拆分成一個個簡單數據,然后分別賦值,如下面代碼:[代碼9:對復雜數據類型進行傳值]

var a = [1, 2, 3] ,b = {name:’張三’,sex:’男’,tel:’1383838438’};var c = [] ,d = {};for(var p in a){ c[p] = a[p]; }for(var p in b){ d[p] = b[p];}c.push(’4’);d.email = ’ibing@outlook.com’;console.info(a); // [1, 2, 3]console.info(c); // [1, 2, 3, '4']console.info(b.email); // undefinedconsole.info(d.email); // ibing@outlook.com

值得一提的是,對于數組的傳值還可以使用數組類的slice或者concat方法實現,如下面代碼:[代碼10:數組傳值的簡單方法]

var a = [1, 2, 3];var b = a.slice(), c = a.concat();b.pop();c.push(4);console.info(a); // [1, 2, 3]console.info(b); // [1, 2]console.info(c); // [1, 2, 3, 4]

prototype本質上也是一個hash對象,所以直接用它賦值時會進行傳址,這也是為什么[代碼7:添加潤行為]中,zs2居然會run的原因。我們可以用for in來遍歷prototype,從而實現prototype的傳值。但因為prototype和function(用做類的function)的關系,我們還有另外一種方法實現prototype的傳值----new SomeFunction(),如下面代碼:[代碼11]

// 定義Person類function Person (name){ this.name = name; this.type = '黃';}Person.prototype={ say : function(){ console.info('我是一個'+ this.type +'種人,我的名字叫' + this.name); }} // 定義Zhangsan類function Zhangsan (name){ Person.call(this,name);}Zhangsan.prototype = new Person();Zhangsan.prototype.constructor = Person;Zhangsan.prototype.run = function(){ console.info('我100米短跑只要10秒!');} // 實例化Zhangsan對象var zs = new Zhangsan('張三');zs.say(); // 我是一個黃種人,我的名字叫張三zs.run(); // 我100米短跑只要10秒!var zs2 = new Person('張三2');zs2.run(); // TypeError: zs2.run is not a function

您是否注意到上面這句Zhangsan.prototype.constructor = Person;,這是因為Zhangsan.prototype = new Person();時,Zhangsan.prototype.constructor指向了Person,我們需要將它糾正,重新指向Zhangsan。

感興趣的朋友可以使用在線HTML/CSS/JavaScript代碼運行工具:http://tools.jb51.net/code/HtmlJsRun測試上述代碼運行效果。

更多關于JavaScript相關內容感興趣的讀者可查看本站專題:《javascript面向對象入門教程》、《JavaScript錯誤與調試技巧總結》、《JavaScript數據結構與算法技巧總結》、《JavaScript遍歷算法與技巧總結》及《JavaScript數學運算用法總結》

希望本文所述對大家JavaScript程序設計有所幫助。

標簽: JavaScript
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
国产农村妇女精品一区二区| 亚洲一级网站| 国产乱码午夜在线视频| 97精品资源在线观看| 国产精品嫩草99av在线| 久久精品三级| 亚洲深深色噜噜狠狠爱网站 | 日韩精品欧美激情一区二区| 免费亚洲婷婷| 日本欧美大码aⅴ在线播放| 快she精品国产999| 久久精品中文| 97精品一区| 久久激情五月激情| 久久国产日韩欧美精品| 亚洲美女91| 免费高清在线一区| 亚洲一区二区日韩| 亚洲中字黄色| 久久午夜影视| 美国三级日本三级久久99 | 久久久久伊人| 日韩高清电影一区| 日韩av午夜在线观看| 五月亚洲婷婷 | 神马日本精品| re久久精品视频| 国产精品7m凸凹视频分类| 亚洲国产成人精品女人| 日韩一区二区三区精品| 日韩高清在线一区| 国产精品久久久久久模特| а√天堂8资源在线| 日本免费久久| 精品视频97| 久久久久91| 午夜国产精品视频| 亚洲3区在线| 国产精品中文字幕制服诱惑| 欧美国产三级| 欧美福利一区| 蜜臀av在线播放一区二区三区| 男女男精品视频网| 麻豆成人91精品二区三区| 97国产精品| 国产一区亚洲| 日韩国产高清在线| 免费视频一区二区三区在线观看| 精品国产美女a久久9999| 午夜电影亚洲| 一区二区三区国产盗摄| 亚洲精品成人| 日韩精品导航| 国产成人精品一区二区免费看京| 日韩一级网站| 日本麻豆一区二区三区视频| 欧美a一区二区| jiujiure精品视频播放| 亚洲精品在线a| 欧美黄色一区二区| 香蕉久久夜色精品国产| 国产日韩欧美中文在线| 神马久久午夜| 日本va欧美va精品发布| 精品三级av在线导航| 91精品推荐| 国产精品美女午夜爽爽| 久久高清免费| 综合精品一区| 毛片在线网站| 中文字幕中文字幕精品| 国产v综合v| 亚洲三级观看| 欧美少妇精品| 国产精品va| 91久久久久| 国产精品久久久免费| 久久国产精品久久久久久电车| 欧美日韩亚洲三区| 黄色亚洲在线| 国产精品白丝久久av网站| 蜜桃国内精品久久久久软件9| 国产精品久久| 久久电影一区| av免费不卡国产观看| 91嫩草精品| 狠狠爱www人成狠狠爱综合网| 精品欧美日韩精品| 免费精品视频在线| 福利视频一区| 国产精品啊v在线| 亚洲一区亚洲| 91欧美在线| 久久wwww| 中文字幕日本一区| 久久97久久97精品免视看秋霞| 免费不卡在线观看| 91精品国产自产在线观看永久∴| 国产精品视频一区二区三区| 午夜在线一区| 欧美一区久久久| 国产一区福利| 欧美一级二级三级视频| 欧洲一区二区三区精品| 精品国产亚洲一区二区三区大结局| 蜜臀91精品一区二区三区| 国产精品久久久久久久久久10秀| 日精品一区二区三区| 91精品国产福利在线观看麻豆| 综合日韩av| 91精品丝袜国产高跟在线| 亚洲视频www| 午夜国产精品视频免费体验区| 精品视频一区二区三区在线观看 | 精品久久影院| 国产精品扒开腿做爽爽爽软件| 最新国产精品久久久| 久久精品国语| 99精品国产一区二区三区| 国产aa精品| 91青青国产在线观看精品| 国产精品久久免费视频| 日韩激情综合| 欧美一级全黄| 亚洲精品看片| 亚洲影视一区| 青青草国产成人99久久| 综合一区在线| 日韩欧美激情电影| 欧美资源在线| av不卡在线看| 日韩专区欧美专区| 免费成人网www| 欧美日韩尤物久久| 亚洲午夜电影| 国产精品久久久久av电视剧| 亚洲成人不卡| 色婷婷精品视频| 日韩一区亚洲二区| 九色精品91| 成人av二区| 激情综合亚洲| 久久国产精品久久w女人spa| 国产一区二区高清| 亚洲一区二区三区四区电影| 日本成人在线视频网站| 午夜精品福利影院| 婷婷视频一区二区三区| 日韩精品欧美大片| 欧美日韩亚洲一区二区三区在线| 久久精品网址| 91麻豆国产自产在线观看亚洲| 欧美一级二区| 欧美好骚综合网| 亚洲爱爱视频| 男女性色大片免费观看一区二区 | 精品亚洲美女网站| 欧美成人基地 | 奇米777国产一区国产二区| 国产精东传媒成人av电影| 国产伦理久久久久久妇女| 国产精品久久久久av蜜臀| 国产在线看片免费视频在线观看| av最新在线| 免费成人在线观看| 国产情侣一区在线| 精品一区视频| 欧美在线首页| 欧美日韩18| 国产精品sss在线观看av| 9999国产精品| 久久影院一区| 久久性天堂网| 成人午夜在线| 婷婷精品视频| 免费久久精品视频| 精品国产一区二区三区2021| 日韩在线中文| 麻豆精品在线观看| 国产一区二区三区自拍| 午夜免费一区| 亚洲欧美在线综合| 亚洲一区日韩| 欧美在线观看视频一区| 精品视频黄色| 高清不卡一区| 精品三级国产| 色欧美自拍视频| 99成人在线视频| 久久97视频| 99精品国产一区二区三区| 婷婷激情图片久久| 国产精品mm| 久久黄色影院| 国产伦理久久久久久妇女| 综合日韩av| 在线精品一区二区| 日韩在线看片| 性欧美69xoxoxoxo| 日韩中文字幕无砖|