摘要:其實(shí)在之前的工廠模式里面,也存在這個(gè)問(wèn)題,不過(guò)工廠模式更徹底,直接完全創(chuàng)建一個(gè)新對(duì)象,而構(gòu)造函數(shù)模式的話只是方法會(huì)被重新創(chuàng)建。
我來(lái)重新學(xué)習(xí) javascript 的面向?qū)ο螅╬art 1)
很多job 的描述都說(shuō)要求精通 javascript 面向?qū)ο缶幊?,但是根?jù)一般的套路,寫(xiě)精通其實(shí)就是熟練,寫(xiě)熟練其實(shí)就是一般,寫(xiě)一般其實(shí)就是懵逼!
雖然話說(shuō)如此,但是我們還是要熟練使用 javascript 面向?qū)ο缶幊痰?,畢竟這是js社會(huì)高能人才的其中一個(gè)標(biāo)準(zhǔn),這里我就用一個(gè)鮮活的例子來(lái)說(shuō)明和理解我們應(yīng)該如何使用javascript 面向?qū)ο蟮姆绞絹?lái)編程。
一、野蠻方式構(gòu)建對(duì)象剛開(kāi)始最初,我們創(chuàng)建對(duì)象的方式是這樣的:
// 。。。。每次都要寫(xiě)上面的一大段代碼,只是為了創(chuàng)建一個(gè) food var food = new Object(); food.name = "蘋(píng)果"; food.sayName = function() { console.log("我是" + this.name); };
但是這樣創(chuàng)建起來(lái)很麻煩,寫(xiě)的代碼也是很長(zhǎng),如果要?jiǎng)?chuàng)建好多對(duì)象,例如我制造了10000個(gè)食物,就要寫(xiě)10000次這一大段代碼了,所以后來(lái)聰明的工程師改為了這樣寫(xiě):
// 起碼比之前的少了幾行,也整潔了一些 var food = { name: "蘋(píng)果", sayName: function() { console.log("我是" + this.name); } };
起碼代碼少了一些,但是還是沒(méi)辦法很好解決我要寫(xiě)100000段代碼的問(wèn)題,所以再后來(lái)的人們就開(kāi)始使用一些高級(jí)玩意來(lái)解決這個(gè)問(wèn)題。
二、使用工廠模式構(gòu)建對(duì)象通過(guò)抽象出創(chuàng)建具體對(duì)象的過(guò)程,用函數(shù)來(lái)進(jìn)行封裝,換句話來(lái)說(shuō),就是抽象了一個(gè) food 的工廠,然后通過(guò)對(duì)這個(gè)工廠傳入不同的材料,來(lái)生成不同的食物。
function createFood(name) { var o = new Object(); o.name = name; o.sayName = function() { console.log("我是" + this.name); }; return o; } var food1 = createFood("蘋(píng)果"); var food2 = createFood("蘋(píng)果");
這里可以看到food1,food2 就是這樣被制造出來(lái)的,然后只需要少量的代碼(預(yù)先定義好一個(gè)生產(chǎn)工廠函數(shù)),就可以完成大量的事情,徹底解決了問(wèn)題,實(shí)現(xiàn)了多快好爽的新局面。但是用了一段時(shí)間之后,隨之而來(lái)發(fā)現(xiàn)一個(gè)新問(wèn)題,當(dāng)食物多起來(lái)的時(shí)候,老板貌似不知道哪些食物是屬于那些分類的(假設(shè)老板是 zz),那怎么辦呢?
// 都統(tǒng)一返回是[Function: Object],沒(méi)辦法用區(qū)分識(shí)別(賣個(gè)關(guān)子,你不用管那個(gè)constructor) console.log(food1.constructor) // 返回[Function: Object] console.log(food2.constructor) // 返回[Function: Object]三、使用構(gòu)造函數(shù)模式來(lái)區(qū)分自己人
經(jīng)過(guò)一番智慧交流之后,聰明的人們想出了一個(gè)方法,使用一個(gè)在對(duì)象里面的 constructor 函數(shù)來(lái)識(shí)別那些不一樣的對(duì)象,類似使用部門工牌來(lái)標(biāo)記這個(gè)人是是屬于哪個(gè)部門的。
function Food(name) { this.name = name; this.sayName = function() { console.log("我是" + this.name); }; } var food1 = new Food("蘋(píng)果"); var food2 = new Food("蘋(píng)果"); // 假設(shè)這里有一個(gè)其他的食物,可能是冒充的 var food3 = new otherFood("蘋(píng)果");
因?yàn)橐獙?shí)現(xiàn)類似工牌的方式來(lái)識(shí)別,所以在創(chuàng)建food的工廠里做一些調(diào)整:
沒(méi)有顯式的創(chuàng)建對(duì)象,例如:var o = new Object();
直接將屬性和方法付給了 this 對(duì)象
沒(méi)有 return 語(yǔ)句
函數(shù)使用了大寫(xiě)字母開(kāi)頭(這里只是為了區(qū)分這個(gè)函數(shù)的特別,按照慣例,大寫(xiě)字母開(kāi)頭的,一般都是 class 或者構(gòu)造函數(shù))
使用了 new 來(lái)創(chuàng)建Food`對(duì)象
做了以上的改變之后,整個(gè)創(chuàng)建對(duì)象的模式被改變了:
首先定義了一個(gè) Food 的構(gòu)造函數(shù)(其實(shí)就是之前的工廠函數(shù)createFood,但是現(xiàn)在升級(jí)了)
通過(guò) new 來(lái)創(chuàng)建一個(gè)對(duì)象(現(xiàn)在的 Food 用 new 來(lái)先創(chuàng)建)
將構(gòu)造函數(shù)的作用域賦值給新對(duì)象,將this指向這個(gè)新對(duì)象(將升級(jí)版的工廠送給這個(gè)用 new 創(chuàng)建的 food)
執(zhí)行構(gòu)造函數(shù)的中的代碼(升級(jí)版的工廠會(huì)自動(dòng)將里面的零件和機(jī)器放到新的 Food 上,相當(dāng)于組裝放在了食物本身 身上)
不需要主動(dòng) return,自動(dòng)返回新對(duì)象(升級(jí)版的工廠會(huì)自動(dòng)返回構(gòu)造好的 food 對(duì)象)
通過(guò)這種方式,我們制造出來(lái)的食物都會(huì)有一個(gè) constructor 為 Food 的標(biāo)記來(lái)標(biāo)識(shí),如果看到不是的話,那肯定就不是我們制造的。
console.log(food1.constructor) // 返回[Function: Food] console.log(food2.constructor) // 返回[Function: Food] console.log(food3.constructor) // 返回[Function: OtherFood] // 檢驗(yàn)的方式有兩種 console.log(food1.constructor == Food) // 返回 true console.log(food2.constructor == Food) // 返回 true console.log(food3.constructor == Food) // 返回 false ,這個(gè)不是我們制造的食物 console.log(food1 instanceof Food) // 返回 true console.log(food3 instanceof Food) // 返回 false,這個(gè)不是我們制造的食物
可以看到,使用了新技術(shù)(constructor模式技術(shù))之后,在沒(méi)有增加工作量的情況下,解決了令人頭痛的問(wèn)題,簡(jiǎn)直是完美,不過(guò)過(guò)了一段時(shí)間之后,發(fā)現(xiàn)好像還是有些瑕疵,使用構(gòu)造函數(shù)constructor模式的時(shí)候,函數(shù)里面的每個(gè)方法都會(huì)在每個(gè)實(shí)例上重新創(chuàng)建一遍,那么最明顯的地方是:
console.log(food1.sayName == food2.sayName); // 返回 false
因?yàn)槭褂?b>new來(lái)創(chuàng)建實(shí)例,new的話還會(huì)把構(gòu)造函數(shù)里面的方法也一起創(chuàng)建,因?yàn)榉椒ㄒ彩呛瘮?shù),而函數(shù)的實(shí)例化也會(huì)被new觸發(fā):
// 省略了其他部分,只關(guān)注方法部分 this.sayName = function() { console.log("我是" + this.name); }; this.sayName = new function() { console.log("我是" + this.name); }();
這樣就會(huì)造成內(nèi)存和時(shí)間和性能的浪費(fèi),明明不需要重新重建新的函數(shù)實(shí)例的。
其實(shí)在之前的工廠模式里面,也存在這個(gè)問(wèn)題,不過(guò)工廠模式更徹底,直接完全創(chuàng)建一個(gè)新對(duì)象,而構(gòu)造函數(shù)模式的話只是方法會(huì)被重新創(chuàng)建。
那怎么解決呢?會(huì)用到原型模式,下回分解。
參考內(nèi)容紅寶書(shū),《javascript 高級(jí)程序設(shè)計(jì)第三版》
版權(quán)信息作者: 慫如鼠
網(wǎng)站: https://www.whynotbetter.com
本作品著作權(quán)歸作者所有,商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/108485.html
摘要:二動(dòng)態(tài)原型模式動(dòng)態(tài)原型模式的特點(diǎn)是,在構(gòu)造函數(shù)里面增加判斷處理是否添加原型對(duì)象屬性。他依然有一個(gè)嚴(yán)重的問(wèn)題,就是原型對(duì)象和實(shí)例和構(gòu)造函數(shù)之間沒(méi)辦法關(guān)聯(lián),這樣不適合在有一定規(guī)模復(fù)雜度的程序開(kāi)發(fā)中使用。 續(xù)上一集內(nèi)容,有一些數(shù)據(jù)不需要共享的時(shí)候,但是又想實(shí)現(xiàn)共享數(shù)據(jù)處理,魚(yú)與熊掌,都要兼得(老板就是這么霸氣),那么經(jīng)過(guò)工程師們的智慧交流,他們發(fā)現(xiàn)現(xiàn)實(shí)并非那么殘酷,還有一些辦法可取的,也就是...
摘要:我是的可以改變函數(shù)的對(duì)象的指向拋出異常,沒(méi)有這個(gè)因?yàn)樽宇惡统惗际菢?gòu)造函數(shù),那么就會(huì)有之前說(shuō)的,構(gòu)造函數(shù)在的時(shí)候,里面的方法函數(shù)會(huì)重復(fù)創(chuàng)建實(shí)例,導(dǎo)致資源浪費(fèi)。 我來(lái)重新學(xué)習(xí)js 的面向?qū)ο螅╬art 4) 續(xù)上一篇,隨著業(yè)務(wù)越來(lái)越大,要考慮一些繼承的玩意了,大千世界,各種東西我們要認(rèn)識(shí)和甄別是需要靠大智慧去分門別類,生物學(xué)中把動(dòng)植物按界、門、綱、目、科、屬、種進(jìn)行分類的方法可能是最有代...
摘要:先來(lái)說(shuō)其實(shí)構(gòu)造函數(shù)也有,原型對(duì)象有,實(shí)例有也有,或者更加籠統(tǒng)的說(shuō),所有對(duì)象都是有的。構(gòu)造函數(shù)的原型對(duì)象上的會(huì)指向構(gòu)造函數(shù)。由于屬性是可以變更的,所以未必真的指向?qū)ο蟮臉?gòu)造函數(shù),只是一個(gè)提示。 續(xù)上一集內(nèi)容,通過(guò)構(gòu)造函數(shù)的方式,成功地更新了生產(chǎn)技術(shù),老板笑呵呵,工人少奔波,只是問(wèn)題總比辦法多,又遇到一個(gè)新問(wèn)題,就是會(huì)造成一些資源的重復(fù)和浪費(fèi),那么經(jīng)過(guò)工程師們的智慧交流,他們產(chǎn)生了一個(gè)新技...
摘要:無(wú)限增殖返回蘋(píng)果返回香蕉返回返回使用的新語(yǔ)法方法會(huì)創(chuàng)建一個(gè)新對(duì)象,使用現(xiàn)有的對(duì)象來(lái)提供新創(chuàng)建的對(duì)象的。是新增的,用來(lái)規(guī)范原型式繼承。這里將返回的新對(duì)象放到子類的原型對(duì)象里面,這樣子類就擁有了父類的原型對(duì)象,也就實(shí)現(xiàn)了方法的繼承。 這是最后的最后了,我會(huì)順便總結(jié)一下各種繼承方式的學(xué)習(xí)和理解。(老板要求什么的,管他呢) 一、繼承-組合繼承、偽經(jīng)典繼承 showImg(https://seg...
摘要:請(qǐng)記住,這些書(shū)中的一些可能不是最新的,但概念和基礎(chǔ)仍應(yīng)適用。是最好的老師之一。的秘密由部分組成。在你完成這些書(shū)后,查看書(shū)籍和最好的本土?xí)? 我看過(guò)三本,第1本,第二本,第四本。第一本買的的實(shí)體書(shū),其他兩本看的是電子書(shū)。第一本是大名鼎鼎老道寫(xiě)的,書(shū)很薄,但是非常經(jīng)典。javascirpt忍者秘籍是jquery的作者寫(xiě)的,也是非常經(jīng)典。you dont kown js系列也是非常好??戳?..
閱讀 1985·2021-11-24 09:38
閱讀 3346·2021-11-22 12:07
閱讀 1917·2021-09-22 16:03
閱讀 1972·2021-09-02 15:41
閱讀 2629·2021-07-24 23:28
閱讀 2219·2019-08-29 13:17
閱讀 1561·2019-08-29 12:25
閱讀 2674·2019-08-29 11:10