《程序員》2008.09期有一篇名爲《無廢話ErLang》的文章,這讓我想到了許多的諸如「無廢話C」、「無
廢話書評」這類的文章,也想到了JavaScript可沒有一篇「無廢話」,因此決定開個篇來寫這個。與這個
決定相關的,索性,此次就寫個最簡單的吧。
聲明一下:若是隻想看複雜的東西,不要讀這篇文章了。
1、JavaScript最初實際上是過程式的
追溯到1.0時代的JavaScript,實際上是過程式的。它的基本特性有隻有兩項,一項是可以直接放在網頁的HTML
標籤中去接管事件,例如:javascript
第二項則是支持一種簡單的對象構造器(函數)。其實這個時代的構造器不如說是初始化函數更合適,它應當
這樣寫:html
因此,早期的JavaScript不容置疑地背上了「基於對象的過程式腳本語言」的名頭,這一點也不冤枉。除了
上面兩項特性,JavaScript有着一些通常性的腳本語言的性質,例如:
-整個.js文件一次性裝載到執行環境(例如WEB瀏覽器)中,在經歷一次語法分析以後,開始逐行執行;
-在上述語法分析週期,(具名的)函數和用"var"聲明的變量被預先處理在一個標識符表中,以便腳本代碼使用;
-從全局的代碼行或函數調用開始執行,整個過程當中執行不到的代碼不被查錯(除第一步中的語法檢錯外)。
也具備一般的過程式語言的性質,例如:
-有if/for/while/switch等語句;
-用function來聲明函數,使用"(..)"來聲明它的形式參數表,以及表示函數調用和傳參;
-相似於C語言的基本語法,包括使用"{..}"來表示代碼塊,以及使用"!="等運算符號;
-一個相似於Java語言的對象操做運算符"."號,和屬性、方法這樣的基本概念。
好了,如今你看到了一個基本的JavaScript語言,它的代碼只有象C同樣的函數與語句行,支持很是簡單的面
向對象編程。OK,這其實也差很少是JavaScript的所有……嗯……所有的語法基礎觀念。若是你用過一門哪怕
稍稍入門一點的程序語言,你都會以爲JavaScript其實挺簡單的。
是啊,「寫個函數,而後調用它」,就這麼簡單。例如:java
2、稍微複雜一點的是數據類型
JavaScript有六種基本數據類型,分爲兩類。一類是值類型,即undefined,string, number和boolean;一類
是引用類型,即function和object。檢測數據X是何種類型,能夠簡單地使用"typeof X"來返回一個字符串。
值類型與引用類型在其它高級語言中,是用「訪問過程當中是傳值仍是傳引用」來區別的。簡單說,在下面函數
中:程序員
X傳入的是值自己,仍是一個指向該值的引用(你能夠想象成指針),代表了X是何種類型。與其它語言不一樣的
是,JavaScript並不在調用入口上加指示字來講明傳值的方法,例如:正則表達式
而是簡單的由腳本引擎根據實際傳入的X的數據類型來決定如何傳值。例如:編程
能這樣處理的關鍵,在於JavaScript類型系統足夠簡潔。六種基本類型包括了三個哲學化的觀念:能執行的
與不能執行的;對象或非對象;有(值)或無(值)。顯然,理解這種哲學性的思想並不容易,由於更復雜一層
的、自包含的邏輯是:函數也是對象、值也是對象、無值也是值。
這就是JavaScript類型系統的所有了。若是你想簡單的用用,那麼你記住下面的就夠了:
-string、number、boolean三種簡單值類型是用來傳給網頁顯示的;
-object用來存放其它的object、funtion或上述簡單值類型,並用'.'運算經過一個屬性名找到它們;
-undefined是用來檢測數據有效無效的;
-function是用來執行的。
固然,若是你要成爲思想家或者語言學的瘋子,那麼去思考上面的哲學化命題吧,我不攔着你。
3、能用鼻子想通的就是直接量了
或許不少人都搞不明白JavaScript中的直接量聲明,然而它確實是很是簡單的。既然咱們大多數高級語言都
支持常量聲明,甚至最原始的彙編語言也支持當即值——例如:數組
那麼JavaScript固然……必然……能夠面無愧色地支持直接量了——他們實際上是一個概念。例如:瀏覽器
只不過在理解的時候,必定要切記:全部上述的代碼中,所謂直接量或當即值,是指那個'256',而不是那
個變量或常量的標識符ABYTE/aByte。更進一步的,你要知道JavaScript支持了8種直接量聲明:
--------------------
數值:支持整數,浮點和0x等進制前綴,以及……等等;
布爾值:true/false;
無值:undefined;
函數:function() { ... },也稱爲匿名函數;
字符串:使用'..'或"..",支持多行和轉義符;
正則表達式:使用/../..,支持g,i,m等正則配置;
數組:使用[..],支持嵌套數組;
對象:使用{...},支持嵌套對象聲明;
--------------------
你能夠把上述字符量做爲一個個體,用在代碼——個人意思是表達式或語句行——的任意位置。用鼻子就能夠
進行的推論是:函數
如上的,你能夠把全部的直接量放在表達式或語句中間。偶爾的,由於語法解析的必要,你可能須要用一對
括號把這個直接量括起來——不然語法上會出現歧義,例以下面這個:this
好了,直接量本來就這麼簡單,你只須要指望本身還有一個沒退化的鼻子就行了。
4、原型繼承
原型繼承多是這個世界上最簡單不過的東西了。
咱們假定一個對象是一張表——偉大的Anders就支持我這個假設,他說JavaScript的對象是「屬性包」——
這樣的一個表中存放的就是「name=value」這樣的「名字/值」對。當咱們想用下面的代碼:
去找值(value)時,就在表裏查一下(用delphi的人應該記得TStringList吧)。對象,哦,所謂對象——在
我曾經的理解裏——就是「帶有繼承關係的結構體(struct/record)」。那麼,繼承關係是?
是這樣,若是上面的查找不成功,對於原型繼承來講,只須要在aObj這個對象的「原型」中找一下,就成了。
這個原型也是一個對象,記錄在構造器函數的prototype屬性中。例如:
當在aObj中找不到name這個屬性時,按照上面的規則,就會去xxx這個對象中找,也就是試圖找找"xxx.name"。
因爲xxx自己也是一個對象,也會有一個構造器函數(例如xxxObject()),所以當xxx.name也找不到時,就會
去xxxObject.prototype裏面去找……如此……如此深層次的挖掘,直到再也找不到……就返回undefined。
多簡單啊,所謂原型繼承,只不過是一個簡單的檢索規則。
反過來講,你須要讓aObj能訪問到某個成員,也只須要修改一下它(或它們——一指相似aObj的實例)的原型
就行了。這在JavaScript中是很是經常使用的。例如你想讓全部的string都有某個屬性:
又例如你想讓全部的對象都有某個屬性(或方法,或其它什麼東東),那麼:
多麼美好,如今String也能getMyName了,函數也能getMyName了,全部沒有名字的也有名字了——固然,名字是undefined。沒名字也是名字,我沒想過你會不會變成哲學瘋子,對不起。