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

您的位置:首頁技術(shù)文章
文章詳情頁

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

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

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

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

Javascript中的實例的屬性和行為是由構(gòu)造函數(shù)和原型兩部分組成的,我們定義兩個類:Person和zhangsan,它們在內(nèi)存中的表現(xiàn)如下圖1:JavaScript中繼承原理與用法實例入門如果想讓Zhangsan繼承Person,那么我們需要把Person構(gòu)造函數(shù)和原型中的屬性和行為全部傳給Zhangsan的構(gòu)造函數(shù)和原型,如下圖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中繼承是要分別繼承構(gòu)造函數(shù)和原型中的屬性和行為的。我們先讓Zhangsan繼承Person的構(gòu)造函數(shù)中的行為和屬性,如下代碼:[代碼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的構(gòu)造函數(shù)中將Person的屬性和行為復(fù)制了一份,與其說是繼承不如說是“真巧,這兩個類的構(gòu)造函數(shù)除了函數(shù)名不同,其他地方都長得一樣”。她的缺點很明顯:如果Person類的構(gòu)造函數(shù)有任何變動,我們也需要手動的同步修改Zhangsan類的構(gòu)造函數(shù),同樣一份代碼,我們復(fù)制了一份寫在了程序中 的不同地方,這違法了DRY原則,降低了代碼的可維護(hù)性。

好了,讓我們來改進(jìn)它:[代碼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的構(gòu)造函數(shù)里調(diào)用Person()函數(shù),希望它內(nèi)部的ths.xxx可以在Zhangsan類的構(gòu)造函數(shù)里執(zhí)行一遍,但奇怪的是,出現(xiàn)“console.info(zs.type);”時,輸出的是undefined,這是怎么回事呢?

這和Person的調(diào)用方式有關(guān)。在JavaScript中,function有兩種不同的調(diào)用方法:

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

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

上面代碼中,Zhangsan類構(gòu)造函數(shù)中的Person是通過函數(shù)方式調(diào)用的,它內(nèi)部的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)

如果想達(dá)到[代碼3]的效果,讓Person內(nèi)部this指向Zhangsan類的實例,可以通過call或apply方法實現(xiàn),如下:[代碼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); // 黃

構(gòu)造函數(shù)的屬性和行為已經(jīng)成功實現(xiàn)了繼承,接下來我們要實現(xiàn)原型中的屬性和行為的繼承。既然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中,賦值語句會用傳值和傳地址兩種不同的方式進(jìn)行賦值,如果是數(shù)值型、不爾型、字符型等基本數(shù)據(jù)類型,在進(jìn)行賦值時會將數(shù)據(jù)直接賦值一份,將賦值的那一份數(shù)據(jù)進(jìn)行賦值,也就是通常所說的傳值;如果是數(shù)組、hash對象等復(fù)雜數(shù)據(jù)類型,在進(jìn)行賦值時會直接用內(nèi)存地址賦值,而不是將數(shù)據(jù)賦值一份,這就是傳址賦值,就是傳數(shù)據(jù)的映射地址。[代碼8:傳值與傳址]

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

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

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

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

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

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本質(zhì)上也是一個hash對象,所以直接用它賦值時會進(jìn)行傳址,這也是為什么[代碼7:添加潤行為]中,zs2居然會run的原因。我們可以用for in來遍歷prototype,從而實現(xiàn)prototype的傳值。但因為prototype和function(用做類的function)的關(guān)系,我們還有另外一種方法實現(xiàn)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測試上述代碼運行效果。

更多關(guān)于JavaScript相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《javascript面向?qū)ο笕腴T教程》、《JavaScript錯誤與調(diào)試技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript遍歷算法與技巧總結(jié)》及《JavaScript數(shù)學(xué)運算用法總結(jié)》

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

標(biāo)簽: JavaScript
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
国产情侣久久| 日韩免费福利视频| 国产精品普通话对白| 亚洲先锋成人| 午夜免费一区| 亚洲一区国产一区| 视频一区二区不卡| 亚洲视频二区| 日韩国产一二三区| 日韩精品亚洲专区在线观看| 亚洲主播在线| 中文字幕日韩欧美精品高清在线| 在线看片日韩| 欧美偷窥清纯综合图区| 国产精品www994| 红杏一区二区三区| 久久大逼视频| 女同性一区二区三区人了人一| 三级亚洲高清视频| 国产精品中文字幕亚洲欧美| 国产精品久久久久久久久久久久久久久 | 六月婷婷综合| 久久精品导航| 亚洲一区二区免费看| 日韩三区四区| 国产精品tv| 天堂中文在线播放| 国产精品免费看| 国产日韩欧美三区| 91欧美日韩| 伊人成人网在线看| 91精品麻豆| 精品国产第一福利网站| 国产一在线精品一区在线观看| 亚洲在线电影| 欧美激情福利| 99久久夜色精品国产亚洲1000部| 午夜在线一区| 久久不见久久见中文字幕免费| 欧美日韩在线观看首页| 国产一级久久| 国产另类在线| 91精品亚洲| 日韩激情中文字幕| 不卡一二三区| 日韩一区二区三区精品| 日韩av自拍| 老鸭窝毛片一区二区三区| 国产精品一区二区精品| 日韩在线观看不卡| 午夜电影一区| 日韩中文字幕不卡| 国产91在线播放精品| 久久都是精品| 久久久久久夜| 免费日本视频一区| 国产精品久久观看| 一区二区三区四区在线观看国产日韩| 国产福利亚洲| 日韩在线播放一区二区| 精品福利久久久| 鲁大师成人一区二区三区| 毛片不卡一区二区| 99香蕉国产精品偷在线观看| 国产欧美大片| 偷拍欧美精品| 精品视频高潮| 中文字幕一区二区av| 久久精品官网| 国产精品igao视频网网址不卡日韩 | 欧美搞黄网站| 免费亚洲婷婷| 亚洲影院天堂中文av色| 偷拍精品精品一区二区三区| 奇米狠狠一区二区三区| 久久国产小视频| 久久99影视| 亚洲日本欧美| 精品在线99| 精品国产日韩欧美精品国产欧美日韩一区二区三区 | 亚洲精品极品少妇16p| 精品日韩一区| 91精品国产自产精品男人的天堂| 午夜欧美理论片| 国产精品精品国产一区二区| 日韩av中文字幕一区| 中文亚洲欧美| 97精品国产福利一区二区三区| 日韩高清不卡一区| 亚洲欧美日韩国产综合精品二区| 日韩在线综合| 精品久久不卡| 国产精品亲子伦av一区二区三区| 在线日韩成人| 亚洲一区欧美二区| 日韩欧美二区| 欧美成人aaa| 911精品国产| 鲁大师成人一区二区三区| 啪啪国产精品| 成人国产精品久久| 久久精品国产福利| 青青在线精品| 亚洲影视一区二区三区| 亚洲一区二区毛片| 亚洲精品888| 欧美日韩精品在线一区| 日韩视频网站在线观看| 精品久久视频| 国产欧美一级| 日韩成人午夜精品| 色综合视频一区二区三区日韩| 视频一区欧美精品| 久久午夜精品一区二区| 国产精品普通话对白| 中文亚洲欧美| 视频一区中文字幕| 久久国产精品久久久久久电车| 99视频一区| 视频一区二区国产| 亚洲精品护士| 日韩亚洲精品在线观看| 日韩中文字幕一区二区高清99| 亚洲精品日韩久久| 日本高清久久| 国产精品一区二区三区av麻| 国产精品乱战久久久| 麻豆精品视频在线| 欧美精品不卡| 亚洲精品福利| 久久精品72免费观看| 亚洲精品中文字幕99999| 免费日本视频一区| 综合欧美亚洲| 日韩欧美在线精品| 国产毛片精品| 成人一区不卡| 久久中文字幕av一区二区不卡| 国产精品91一区二区三区| 亚洲自啪免费| 亚洲精品动态| 国产精品久久久久9999高清| 国产一区二区亚洲| 日韩一区二区中文| 五月天久久网站| 综合亚洲视频| 国产精品2区| 97国产精品| 亚洲激情二区| 日韩不卡在线观看日韩不卡视频| 国产精品午夜一区二区三区| 91免费精品| 中文国产一区| 国产亚洲精aa在线看| 国产aa精品| 中文一区二区| 国产精品一在线观看| 成人日韩在线| 久久午夜影视| 久久99性xxx老妇胖精品| 欧美香蕉视频| 天使萌一区二区三区免费观看| 欧美亚洲三区| 五月天av在线| 亚洲精品在线a| 成人在线丰满少妇av| 亚洲激情偷拍| 国产欧美在线| 蜜桃视频在线网站| 中文一区一区三区免费在线观| 国产精品3区| 欧洲激情综合| 国产精品欧美三级在线观看| 久久人人精品| 日韩精品欧美大片| zzzwww在线看片免费| 另类av一区二区| 欧美激情亚洲| 国产农村妇女精品一二区| 国产精品乱战久久久| 美女久久久久| 国产欧美亚洲一区| 九一成人免费视频| 国产日韩一区二区三区在线| 久久激情一区| 国产乱人伦精品一区| 欧美日韩视频| 免费一区二区三区在线视频| 亚洲一区免费| av最新在线| 婷婷精品在线| 亚洲精品.com| 亚洲精品欧洲| 亚洲www啪成人一区二区| 欧美亚洲三级| 男女精品网站| 色老板在线视频一区二区| 欧美精品国产白浆久久久久| 在线 亚洲欧美在线综合一区| 国模大尺度视频一区二区|