新聞中心
1.前言

十年的蒼梧網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開(kāi)發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。營(yíng)銷(xiāo)型網(wǎng)站建設(shè)的優(yōu)勢(shì)是能夠根據(jù)用戶(hù)設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整蒼梧建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無(wú)論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)從事“蒼梧網(wǎng)站設(shè)計(jì)”,“蒼梧網(wǎng)站推廣”以來(lái),每個(gè)客戶(hù)項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。
作為Java 帝國(guó)的未來(lái)繼承人,Java小王子受到了嚴(yán)格的教育, 不但精通Java語(yǔ)言、Java虛擬機(jī)、java類(lèi)庫(kù)和框架,還對(duì)各種官方的Java規(guī)范了如指掌。
近日他聽(tīng)說(shuō)一個(gè)叫做Javascript的屌絲逆襲了, 成功地建立了一個(gè)獨(dú)立的王國(guó), 不但成了前端編程之王, 還不斷地蠶食Java帝國(guó)的領(lǐng)地 !
按照小王子宮廷老師的說(shuō)法: 想當(dāng)年, 這家伙只是運(yùn)行在瀏覽器中,完完全全是蹭了Java的熱度這才發(fā)展起來(lái), 現(xiàn)在竟然回過(guò)頭來(lái)要欺負(fù)我們, 還有沒(méi)有天理了? 是可忍孰不可忍? !
小王子可不這么認(rèn)為, 存在必然是合理的,javascrip必有獨(dú)特之處, 俗話(huà)說(shuō)知己知彼,百戰(zhàn)不殆,他覺(jué)得有必要去Javascript王國(guó)刺探一下,搜集一下情報(bào), 看看這個(gè)曾經(jīng)的瀏覽器中的面向?qū)ο笳Z(yǔ)言是怎么回事, 為什么那么多碼農(nóng)趨之若鶩。
2.初步印象
喬裝打扮以后,小王子來(lái)到Javascript 王國(guó),這里看起來(lái)一派生氣勃勃的景象,人們隨性而奔放, 不像Java帝國(guó)那么嚴(yán)肅而呆板, 讓人感覺(jué)心情愉悅。
不過(guò)令小王子感到不可思議的是, 這里竟然沒(méi)有官方提供的類(lèi)庫(kù)! 人們干活用的工具五花八門(mén),讓人眼花繚亂, 什么AngularJS, React , Backbone,Vue, Ember,JQuery, ...... 互相之間還吵來(lái)吵去,爭(zhēng)來(lái)爭(zhēng)去,煞是熱鬧。
對(duì)比這下,Java帝國(guó)有著嚴(yán)密的統(tǒng)治,有著官方提供的龐大類(lèi)庫(kù), 還有一統(tǒng)天下的Web框架 SSH/SSM ,再加上各種各樣的Java規(guī)范, 碼農(nóng)們只需要拿來(lái)學(xué)習(xí),干活就行。
沒(méi)有了選擇的煩惱, 但同時(shí)也減少了選擇的權(quán)利, 是好還是壞? 小王子自己也不知道。
小王子還注意到Javascript王國(guó)的人寫(xiě)程序幾乎沒(méi)人使用IDE, 找個(gè)趁手的文本編輯器就可以開(kāi)工, 然后扔到瀏覽器中去運(yùn)行測(cè)試,真是輕量級(jí)啊! 唉, 我們Java帝國(guó)還在爭(zhēng)論IntelliJ IDEA和Eclipse孰優(yōu)孰劣, 實(shí)在是沒(méi)有必要啊。
3.沒(méi)有類(lèi)怎么創(chuàng)建對(duì)象?
隨著調(diào)查的深入,小王子愈發(fā)覺(jué)得吃驚, 這里竟然沒(méi)有類(lèi)的概念! 一個(gè)面向?qū)ο蟮恼Z(yǔ)言竟然沒(méi)有類(lèi)! 這和小王子從出生就被灌輸?shù)母拍羁墒潜车蓝Y!
沒(méi)有類(lèi)怎么創(chuàng)建對(duì)象 ? 小時(shí)候?qū)m廷老師經(jīng)常說(shuō): 先寫(xiě)一個(gè)類(lèi), 然后才能從這個(gè)類(lèi)new出一個(gè)對(duì)象出來(lái) 。
可是眼前卻有著無(wú)數(shù)的javascript對(duì)象, 他們?cè)诓粩嗟禺a(chǎn)生、消亡,一起辛苦地工作,支撐起龐大的、生機(jī)勃勃的帝國(guó)。
這些對(duì)象是從哪里來(lái)的? 小王子百思不得其解, 正值正午時(shí)分, 小王子看到前面有一家JSON酒館,決定先歇歇腳,美美地吃一頓再說(shuō)。
小王子要了二斤熟牛肉,三碗酒,正要開(kāi)始享用, 只聽(tīng)到旁邊桌子的一個(gè)穿著長(zhǎng)袍的人問(wèn)道:哎,你說(shuō)的那個(gè)對(duì)象的原型是什么?
另一位戴眼鏡的則低聲說(shuō):噓,噤聲,國(guó)王剛頒布命令,原型法是我們帝國(guó)的秘密,禁止公開(kāi)討論,以防被Java帝國(guó)給學(xué)了去。
小王子心中一動(dòng), 馬上把小二叫來(lái),要來(lái)上等酒菜, 送到鄰桌,請(qǐng)兩位吃酒。 一番酒喝下來(lái), 小王子終于獲得了兩人的初步信任, 原來(lái)他們還是負(fù)責(zé)審查javscript語(yǔ)言規(guī)范的官員。
小王子問(wèn)道: “我家世代經(jīng)商, 走南闖北,去過(guò)C++王國(guó),Java帝國(guó), C#帝國(guó), 他們都是號(hào)稱(chēng)面向?qū)ο蟮恼Z(yǔ)言, 都有class 和 object的區(qū)分, 可是到了咱們javascript王國(guó), 我怎么連一個(gè)class 都沒(méi)有看到啊? ”
戴眼鏡的官員說(shuō): “我們不用class, 那玩意兒太不直觀了 !”
小王子暗暗稱(chēng)奇, 可是仔細(xì)一想, 好像就是這樣啊, 想當(dāng)初我學(xué)習(xí)Java的時(shí)候, 費(fèi)了好大的勁才接受了class這個(gè)概念,實(shí)際上面向?qū)ο蟮南到y(tǒng),不就是對(duì)象之間的交互嗎? 要類(lèi)干什么?
然后小王子問(wèn)了一個(gè)關(guān)鍵問(wèn)題: “沒(méi)有class, 怎么創(chuàng)建對(duì)象啊”
“外鄉(xiāng)人, 沒(méi)那么復(fù)雜,你想想什么是對(duì)象啊,不就是屬性加上方法嗎? 你看看我們這就創(chuàng)建一個(gè)對(duì)象出來(lái) ” 這位官員說(shuō)著,手指頭沾著酒水在桌子上寫(xiě)了起來(lái):
看到?jīng)]有,這個(gè)animal對(duì)象定義了一個(gè)屬性name, 和一個(gè)方法 eat , 簡(jiǎn)單吧?”
的確是簡(jiǎn)單又明了,完全不需要class, 一個(gè)對(duì)象就創(chuàng)建了,小王子面前似乎打開(kāi)了一扇新的大門(mén)。
“由于對(duì)象并不和類(lèi)關(guān)聯(lián), 我們可以隨意地給這個(gè)對(duì)象增加屬性:” 眼鏡官員補(bǔ)充到。
“還能這么玩?!” 小王子被驚到了,沒(méi)有類(lèi)的約束,這些對(duì)象也太自由了吧。
4.沒(méi)有類(lèi)怎么繼承?
“那繼承怎么實(shí)現(xiàn), 繼承可是面向?qū)ο蟮闹匾拍畎 ?/p>
眼鏡官員說(shuō): “簡(jiǎn)單啊,繼承不就是讓兩個(gè)對(duì)象建立關(guān)聯(lián)嘛! 在我們javascript王國(guó),每個(gè)對(duì)象都有一個(gè)特殊的屬性叫做__proto__, 你可以用這個(gè)屬性去關(guān)聯(lián)另外一個(gè)對(duì)象(這個(gè)對(duì)象就是所謂的原型了) , 來(lái)我給你畫(huà)一下”
這段酒水寫(xiě)成的代碼不長(zhǎng),但是卻深深地震撼了小王子, 因?yàn)槠渲行畔⒘糠浅>薮螅[藏了“原型”的秘密, 小王子不由得陷入了深思:
對(duì)象dog 的原型是animal (注意:也是一個(gè)對(duì)象), 對(duì)象cat的原型也是animal 。
無(wú)論是dog還是cat ,都沒(méi)有定義eat()方法, 那怎么可以調(diào)用呢?
當(dāng)eat方法被調(diào)用的時(shí)候,先在自己的方法列表中尋找, 如果找不到,就去找原型中的方法, 如果原型中找不到, 就去原型的原型中去尋找...... ***找到Object那里, 如果還找不到, 那就是未定義了。
這里的這幾個(gè)對(duì)象肯定是通過(guò)__proto__建立了一個(gè)原型鏈!
嗯, 我?guī)煾附o我講JVM虛擬機(jī)的時(shí)候, 也提到了一個(gè)對(duì)象在執(zhí)行方法的時(shí)候,需要查找方法的定義,這個(gè)查找的次序也是先從本對(duì)象所屬的類(lèi)開(kāi)始, 然后父類(lèi), 然后父類(lèi)的父類(lèi)...... 直到Object, 思路是一模一樣的!
只不過(guò)Java 的方法定義是在class中, 而這個(gè)javascript 的方法就在對(duì)象里邊, 現(xiàn)在我覺(jué)得似乎在對(duì)象里更加直觀一點(diǎn)啊。
屬性和方法應(yīng)該類(lèi)似,也是沿著原型鏈向上查找, 不過(guò)這里dog的name屬性似乎覆蓋了animal的name屬性, 還有那個(gè)this, 在調(diào)用dog.eat()的時(shí)候,應(yīng)該是指向dog這個(gè)對(duì)象的。
看來(lái)面向?qū)ο蟮睦砟疃际窍胪ǖ陌 ?想著想著,小王子臉上竟然露出了笑容。
看到小王子像程序卡住一樣,不動(dòng)了, 穿長(zhǎng)袍的官員推了小王子一把: 外鄉(xiāng)人, 你怎么了?
小王子意識(shí)到自己的失態(tài), 趕緊說(shuō): “哦,沒(méi)啥, 我覺(jué)得你們使用的這個(gè)’原型‘的辦法很精妙啊, 完全不用類(lèi)就實(shí)現(xiàn)了繼承?!?/p>
眼鏡官員一愣: “外鄉(xiāng)人, 看來(lái)你悟性不錯(cuò), 帝國(guó)的秘密已經(jīng)被你給洞察了, 不過(guò)很多新來(lái)的程序員就不容易體會(huì)到這一點(diǎn), 于是我們就做了一個(gè)變通, 讓javascript可以像Java那樣new 出對(duì)象出來(lái)。說(shuō)來(lái)慚愧, 這完全是為了遷就那些C++,Java, C#程序員啊 ”
5.向Java靠攏
小王子說(shuō):”什么變通辦法? 難道你們也開(kāi)始使用類(lèi)了嗎?“
“不不, 我們提供了一個(gè)叫做構(gòu)造函數(shù)的東西。還是給你寫(xiě)點(diǎn)兒代碼吧 ” 官員說(shuō)著,又蘸著酒水寫(xiě)了起來(lái):
小王子說(shuō)道: “那個(gè)function 已經(jīng)有點(diǎn) class的感覺(jué)了啊, 天吶我竟然看到了this這個(gè)關(guān)鍵字, 對(duì)了那個(gè)Student是你故意寫(xiě)的大寫(xiě)嗎? ”
“是啊 , 這樣以來(lái)看起來(lái)就像Java的類(lèi)了。但是,中間有個(gè)問(wèn)題,你看出來(lái)了嗎? ”
小王子想了一陣:“ 是不是說(shuō)每個(gè)新創(chuàng)建對(duì)象都有一個(gè)sayHello函數(shù)? 在Java中函數(shù)都是定義在class 上的。 如果定義對(duì)象上, 那就意味著每個(gè)對(duì)象都有一份, 太浪費(fèi)了?!?/p>
“是的,所以我們得提供一種更加高效的辦法, 把這個(gè)sayHello函數(shù)放到另外一個(gè)地方去! ”
“放到哪里? ”
“記得我們剛才說(shuō)的原型鏈嗎? 當(dāng)一個(gè)對(duì)象調(diào)用方法的時(shí)候,會(huì)順著鏈向上找,所以我們可以創(chuàng)建一個(gè)原型對(duì)象,其中包含sayHello函數(shù), 讓andy, lisa這些從Student創(chuàng)建起來(lái)的對(duì)象指向這個(gè)原型就ok了。”
“可是你這里只有構(gòu)造函數(shù)Student, 在哪里創(chuàng)建原型對(duì)象呢? 怎么把a(bǔ)ndy,lisa 這些對(duì)象的__proto__指向原型對(duì)象呢? 不會(huì)讓我手工來(lái)指定吧?!?/p>
眼鏡官員瞪了一眼小王子說(shuō): “我們javascript帝國(guó)肯定不會(huì)這么麻煩程序員的, 我們可以把這個(gè)原型對(duì)象放到Student.prototype這個(gè)屬性中(注意,不是__proto__), 這樣一來(lái),每次當(dāng)你創(chuàng)建andy,lisa這樣的對(duì)象時(shí), javascript 就會(huì)自動(dòng)的把原型鏈給建立起來(lái)!”
小王子面露難色:“唉,這理解起來(lái)有點(diǎn)難啊?!?/p>
"還是畫(huà)個(gè)圖吧, 當(dāng)你去new Student的時(shí)候,javascript會(huì)建立這樣的關(guān)系鏈:"
小王子說(shuō): “明白了,這個(gè)所謂的構(gòu)造函數(shù)Student 其實(shí)就是一個(gè)幌子啊, 每次去new Student的時(shí)候,確實(shí)會(huì)創(chuàng)建一個(gè)對(duì)象出來(lái)(andy或者lisa) , 并且把這個(gè)對(duì)象的原型(__proto__)指向 Student.prototype這個(gè)對(duì)象,這樣一來(lái)就能找到sayHello()方法了?!?/p>
眼鏡官員回答:“沒(méi)錯(cuò),這個(gè)地方容易讓人混淆的就是__proto__和prototype這兩個(gè)屬性, 唉,我也不知道最早為什么這么干, 實(shí)在是不優(yōu)雅?!?/p>
“是啊,這個(gè)構(gòu)造函數(shù)再加上prototype的概念,實(shí)在是讓人費(fèi)解, 所以我們商量著提供一點(diǎn)語(yǔ)法糖降低程序員的負(fù)擔(dān)?!?長(zhǎng)袍官員附和到。
6.語(yǔ)法糖
聽(tīng)到語(yǔ)法糖,小王子覺(jué)的很親切, 因?yàn)镴ava 中也提供了很多方便程序員的語(yǔ)法糖。
當(dāng)長(zhǎng)袍官員寫(xiě)出javascript的語(yǔ)法糖的時(shí)候, 小王子不由得大吃一驚:
這語(yǔ)法糖已經(jīng)把javascript變得非常像Java, C#,C++的類(lèi)了, 看來(lái)javascript帝國(guó)為了“討好”程序員, 已經(jīng)努力的在改變了, 我們java帝國(guó)看來(lái)得加油啊。
小王子現(xiàn)在明白了Javascript是一個(gè)基于原型實(shí)現(xiàn)的面向?qū)ο蟮恼Z(yǔ)言, 根本沒(méi)有類(lèi)的概念, 新的方式給小王子的思維觀念帶來(lái)了重大的沖擊。
在這里待久了,他又了解到j(luò)avascript強(qiáng)大的函數(shù)式編程,越來(lái)越喜歡javascript, 都有點(diǎn)樂(lè)不思蜀了。
小王子還會(huì)回到Java帝國(guó)嗎?
【本文為專(zhuān)欄作者“劉欣”的原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)通過(guò)作者微信公眾號(hào)coderising獲取授權(quán)】
戳這里,看該作者更多好文
標(biāo)題名稱(chēng):JavaScript王國(guó)的一次旅行,一個(gè)沒(méi)有類(lèi)的世界怎么玩轉(zhuǎn)面向?qū)ο螅?
網(wǎng)站地址:http://www.5511xx.com/article/dhoicpi.html


咨詢(xún)
建站咨詢(xún)
