如果理解不了什么是面向?qū)ο笤脖怯惺裁幢匾ダ斫舛逖叮恳苍S換個角度想想,我們理解了面向?qū)ο竽芨蓡幔?/p>
“javascript面向?qū)ο蟆毖撑笆裁词莏avascript面向?qū)ο蟆钡对啵笆裁词莗rototype和__proto__”,“什么是Object和Function”...........等等諸如這一系列問題。
我相信你不止一次在百度搜索這些關(guān)鍵字超凳,而且確信你點(diǎn)開一個搜索內(nèi)容看的前幾句一般都是諸如此類的解釋:
“函數(shù)才有prototype對象有__proto__”
“對象:對象是一個整體愈污,對外提供一些操作”
“面向?qū)ο蟮恼Z言有一個標(biāo)志,那就是類的概念轮傍,而通過類可以創(chuàng)建任意多個具有相同屬性和方法的對象暂雹。但是,ECMAScript 沒有類的概念创夜,因此它的對象也與基于類的語言中的對象有所不同杭跪。”挥下。揍魂。。棚瘟。。
.........................................我更相信你看了一篇博文前面幾句然后又點(diǎn)開下一篇博文如此反復(fù)
接著就抽根煙開始懷疑人生喜最,“難道我學(xué)不會javascript”
當(dāng)你點(diǎn)開這篇文章的時候偎蘸,你應(yīng)該還是沒有理解,我相信你是花了很多時間才找到的,因?yàn)槲业牟┛筒怀雒?/p>
既然如此累還是搞不懂我們和不妨靜下心來迷雪,休息一會限书,拉會家常,
生活章咧,沒必要把自己搞得那么狼狽不堪倦西,那么累
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
?正文
在開始擺龍門陣之前,我要求你放下面向?qū)ο罅扪希彤?dāng)不存在這個概念扰柠。因?yàn)槊嫦驅(qū)ο蟊緛砭褪且环N描述抽象事物的形容詞叫法。重要的事情說三遍疼约,"放下面向?qū)ο?卤档,反正你都不理解那要他何用?(你叫貓的名字它不過來程剥,那為什么要給他取名字勒劝枣?)
第一步:(預(yù)備知識)
? ? 1:首先你應(yīng)該具備基礎(chǔ)知識(相信你看到這篇博客應(yīng)該是具備了)
????2:其次你應(yīng)該對對象為什么"引用類型"有一個比較抽象的理解(比如能用生活當(dāng)中的例子舉例)
? ?3:對函數(shù)的屬性和作用于以及this有那么一點(diǎn)深入了解,知道什么是上下文會更好(一會用的不多)织鲸,prototype和__proto__知道就行舔腾,主要就是扯他們
第二步(我們從一個故事開始入手)
"萬物都有根,一切皆無形"(講一個中國傳統(tǒng)的故事:女媧造人應(yīng)該知道吧搂擦,創(chuàng)世女神女媧化生萬物?[1]?稳诚,每天至少能創(chuàng)造出七十樣?xùn)|西?[2]?,開世造物盾饮,因此被稱為大地之母[3-6]?采桃。她是古老相傳的大母神。相傳女媧以泥土仿照自己摶土造人丘损,創(chuàng)造并構(gòu)建人類社會普办;又替人類立下了婚姻制度,使青年兩性相互婚配徘钥,繁衍后代衔蹲,因此也被傳為主職姻緣與情愛的皋禖古神。)
?那么問題來了:女媧是誰造的呈础?
你要是解釋清楚了那我們就無話可說了舆驶,但如果我們要是解釋不清楚怎么辦?
答案:涼拌而钞,既然解釋不清楚那我們何不把他當(dāng)真相去對待沙廉?不過我們可以試圖去尋找真相
Object()是什么?
function fun(){......}? ? ? ? ? ?function Person(){......}
Object()和fun()以及Person()他們其實(shí)就是一個函數(shù)
function Object(){......}//調(diào)用函數(shù)就要寫成Object()
但是為什么我們直接打開編輯器什么都不寫直接console.log(Object())或者瀏覽器控制臺直接Object()會創(chuàng)建一個對象臼节,那為什么console.log(fun())就報錯勒撬陵;--》那是不是說明javascript本身就有Object這個函數(shù)珊皿,而沒有fun--》這就是內(nèi)置構(gòu)造函數(shù)
那什么是--------構(gòu)造函數(shù)?
我們從文字表面來理解"構(gòu)造"兩個字(注意巨税,不包含“函數(shù)兩個字”):比如我需要一件衣服蟋定,那么我是不是要去商店買一件衣服。那么我現(xiàn)在需要生產(chǎn)衣服草添,那你是不是的建一個生產(chǎn)衣服的工廠笆欢怠?當(dāng)然远寸,你也可以手工一件一件的做抄淑,工廠做一百件你同樣能做一百件。
(先不說賣衣服)我生產(chǎn)一件衣服的情況就好比我需要一個對象
var obj = {
name:"adidashi",
? ? ? ? color:"red",
? ? ? ? ?temperature:function(){........}
}
那如果我要生產(chǎn)10件怎么辦而晒,(有的婦女確實(shí)能織出十件甚至更多)蝇狼,那我要生產(chǎn)100件,1000件怎么辦呢倡怎?難道你要寫一百個一千個對象迅耘?,顯然都是一樣的衣服一樣重復(fù)的代碼
那么只有建立工廠监署,(就比如說你真的要生產(chǎn)衣服(大規(guī)模的)在現(xiàn)實(shí)生活當(dāng)中你也必須要建立工廠)
如何創(chuàng)建工廠:
首先得選地方颤专,那么我們就用函數(shù)吧?
接著工廠造好了钠乏,是不是得有那么一個模板栖秕,就比如街上那種小蛋糕,他是用模板一次可以做很多個晓避,如果用手捏一次只能捏一個簇捍,制衣廠那種流水線
模板:對于模板生產(chǎn)出來的東西就只有一個有共同點(diǎn),"都是一樣的"俏拱。同一個批次的衣服品牌一樣把暑塑,大小一樣把,顏色一樣把...................
//锅必,工廠建好了我們是不是需要對原料進(jìn)行加工事格,然后出廠
第一步:原料(就是一個空對象)
? ? var obj={}
第二步:我們需要對原料加工
????obj .name="adidas"
obj .color="red"
obj .temperature=function(){.........}
第三步:出廠
? ? ? return obj;
}
出廠的目的就是讓別人來買啊搞隐,假設(shè)有兩個人來買驹愚,
var person1=GarmentFactory( );
var person2=?GarmentFactory( );
弊端:如果所有對象name的值不一樣要去改函數(shù)源代碼或者對象自己本身(person1),那樣應(yīng)該很麻煩吧劣纲,那么為什么我們不可以通過參數(shù)賦值呢逢捺?后面會解決的
這兩個人如果要買衣服那么就是說他們必須要?dú)v經(jīng)造一個工廠(重復(fù)調(diào)用函數(shù),這是性能問題了)癞季,買原料蒸甜,出廠棠耕,其實(shí)說白了余佛,就是對象字面量的簡寫柠新,"但是我們的這個工廠的確是模板的一個完美解釋"與其寫十個字面量一樣的對象,不如用函數(shù)吧把他們的共同點(diǎn)裝在一起辉巡,需要衣服就去調(diào)用一函數(shù)恨憎。
那么問題又來了?
為什么我要買一件衣服郊楣,就要去建一個工廠憔恳,買十件衣服就要建十個工廠(相當(dāng)于在計算機(jī)內(nèi)存開辟十個存儲空間然后又不要這十個空間如此反復(fù)),明明都是一樣的衣服净蚤,很顯然這是沒必要的钥组,那么我們?nèi)绾巫龅街恍枰粋€工廠而做到不需要每次買衣服就建工廠勒?
new:我們需要一個代理人今瀑,和工廠聯(lián)系3堂巍!橘荠!
new(官網(wǎng)有解釋):運(yùn)算符屿附,任何函數(shù)都可以new,用來初始化對象的哥童,一旦通過new調(diào)用的函數(shù)就叫構(gòu)造函數(shù)挺份,(你自己開工廠造衣服你叫老板,而你通過代理人買衣服你叫顧客贮懈,然而你還是你匀泊,同樣的,你當(dāng)老板干的事和你當(dāng)顧客或者代理人的事情都不一樣"你爸爸叫你叫兒子朵你,你爺爺叫你叫孫子")
既然new是代理人各聘,那么肯定有過人之處,在使用new的過程撬呢;
1:在函數(shù)內(nèi)部生成一個對象(空對象){ }
2:吧函數(shù)內(nèi)部this引用綁定到這個對象上
3:隱式的返回這個對象(那么也就是說new表達(dá)式的值是這個對象)
function GarmentFactory(){
1:在函數(shù)內(nèi)部生成一個對象(空對象){ }//對程序員不可見
? ? ? ? var obj={}
2:吧函數(shù)內(nèi)部this引用綁定到這個對象上伦吠,這是硬行規(guī)定
? ? ? ? obj.name="adidas"
? ? ? ? obj.color="red"
? ? ? ? obj.temperature=function(){}
3:隱式的返回這個對象(那么也就是說new表達(dá)式的值是這個對象(那么也就是說new表達(dá)式的值是這個對象當(dāng)然也可以顯示返回,不過沒必要魂拦,自己去了解))
? ? ? ? return obj;
}
簡寫如下形式==》
function GarmentFactory(name,color){
? ? ? ? this.name=name
? ? ? ? this.color=color
? ? ? ? this.temperature=function(){}
}
var obj = newGarmentFactory()
注意:第二步已經(jīng)將this綁定到返回的這個對象毛仪,而對象又通過賦值給了obj,他們的區(qū)別在于obj什么都不是芯勘,就像你的名字什么也不是箱靴,但總得用個什么名字稱呼你這個實(shí)體吧!:摄怠衡怀!那么this就指向了obj棍矛,他就有屬性和方法了,到這里了抛杨,我們給obj下一個定義够委,“他通過這么復(fù)雜的方式創(chuàng)建的對象特殊在哪里?即便每次創(chuàng)建對象依然是去調(diào)用一遍函數(shù)”-----》實(shí)際上和字面量是一樣的怖现,那為什么要用怎么復(fù)雜的方式創(chuàng)建對象茁帽?
任何復(fù)雜的方法都是為了去解決更復(fù)雜的事情,
假設(shè)你現(xiàn)在還在生產(chǎn)衣服屈嗤,那么就會有一個問題(這應(yīng)該不算是問題)潘拨,明明每一個衣服都有名字,而且都是相同的饶号,那為什么我們要給每一個衣服取個名字(是不是暈了)铁追。再舉個例子,人一生下來是不會走路的茫船,那我為什么不跟著別人學(xué)走路而要自己發(fā)明一個怎么走路呢琅束?每個人都會走路,但大家走路的姿勢又各不相同透硝,總之目的都是一樣的狰闪,
現(xiàn)在我們先把這個工廠放在一邊,我們說說人(就我們自己的特征)
相親除了問你有什么或者會什么他還能問什么(博主是遭遇過的)
1濒生,人都有什么:每個人都有名字埋泵,年齡,眼睛罪治,鼻子...........這些屬于一個人的基本特征吧(或者叫屬性)(這些都是有狀態(tài)的丽声,比如年齡會增加,名字會改變觉义,但他們能殺人放火嗎雁社?)
2,人都會什么:每個人都會吃飯晒骇,睡覺霉撵,談戀愛等等。洪囤。徒坡。。瘤缩。這些屬于一個人行為吧(這些沒有什么狀態(tài)喇完,但他們是行為,是為了操作狀態(tài)剥啤,語文當(dāng)中動詞描述的哪一類)
總結(jié):我們把這寫人的基本特征或者基本行為定義為一個模板锦溪,我們是不是就可以造小人了不脯,就比如女媧把他自己當(dāng)成模板
那我們就開始女媧造人(我們這里要假設(shè)人可以在一秒鐘學(xué)會走路,不然故事沒法編了)
function Person(name,color){
? ? ? ? this.name=name
? ? ? ? this.age=18
? ? ? ? this.eat=function(){}
}
var obj1=?Person()
var obj2=?Person()
var obj3=?Person()
在上面的例子當(dāng)中刻诊,obj1防楷,obj2,obj3都是一個個具體的人坏逢,他們都可以有名字域帐,年齡,會吃飯等一系列人所具備的(只是我寫的少而已)是整,那么我們不禁思考一個問題,每個人的名字的確不一樣民假,年齡也是不一樣的浮入,但每個人張嘴吃飯的動作確是一樣的,在程序當(dāng)中羊异,你new出來的實(shí)例(就是obj123)他們就相當(dāng)于我們?nèi)松聛聿皇歉改笇W(xué)走路的事秀,而是自己摸索怎么走路的。娶一個名字幾秒鐘就夠了野舶,但是走路就算有人教也得幾年吧易迹?
這個時候,就得有一個相對祖先平道,把她會的繼承下來睹欲,而不是我們每個人都去發(fā)明自己怎么走路
(當(dāng)然,人本來就是可以繼承一屋,但程序中的繼承是你生下來馬上就會走路蹦迪遛狗了)
prototype就是祖先(官方解釋不想說了)
只有函數(shù)才有prototype屬性窘疮,而他的屬性值是一個對象(就是一個普通對象)
//下午接著扯嘱巾,困會瞌睡