JavaScript 函數(shù)和對(duì)象
首先是一段獨(dú)白跳夭,與正文無(wú)關(guān)亡笑,可直接跳過(guò)下面的段落。
接下來(lái)要聊的東西我還沒(méi)有特別清晰的思路最仑,不過(guò)考慮到我們都是“在路上”,所以沒(méi)必要面面俱到炊甲。因此泥彤,我會(huì)把我了解的,平時(shí)用到的卿啡,都拿出來(lái)分享吟吝。但這些顯然不是我們現(xiàn)在涉及的領(lǐng)域的全部,甚至可能不是主要的部分颈娜。不過(guò)剑逃,相信你并不會(huì)因此而苛責(zé)我吧,因?yàn)槟惝吘共皇窃谧x一本專業(yè)書官辽,帶著挑剔的專業(yè)的眼光(_)蛹磺。
函數(shù)與對(duì)象啥關(guān)系
在 JavaScript 中,很多東西都可以看做對(duì)象同仆,不過(guò)就像咱們青年也分為:2B青年萤捆,普通青年與文藝青年一樣,在這里請(qǐng)?jiān)试S我冒昧地把 JavaScript 中的對(duì)象也分分類。當(dāng)然俗或,請(qǐng)注意市怎,我保證這不會(huì)是官方的或者是學(xué)術(shù)上的分類。
在這里蕴侣,我把 JavaScript 的對(duì)象分為:
- 隱式對(duì)象:包括數(shù)值焰轻,字符串臭觉,數(shù)組昆雀。
- 內(nèi)置對(duì)象:由語(yǔ)法規(guī)范定義或由運(yùn)行環(huán)境提供的一些對(duì)象,例如正則表達(dá)式蝠筑、日期狞膘、HTMLElement 對(duì)象等等。
- 普通對(duì)象:簡(jiǎn)單來(lái)說(shuō)就是類似
{ name: "luobo" }
這樣聲明的一個(gè)對(duì)象什乙。 - 函數(shù)對(duì)象:其實(shí)就是函數(shù)挽封,但同樣也是對(duì)象,只不過(guò)有被“調(diào)用”的“大招”臣镣。
隱式對(duì)象
舉個(gè)栗子:
var s = "Hello, luobo!";
s.substr(7, 5); // "luobo"
把這里的 s
看做對(duì)象辅愿,是因?yàn)樗小胺椒ā卑∫淠常∧阏f(shuō)是不是很合理啊点待。當(dāng)然,任何道理有時(shí)候都像是“強(qiáng)詞奪理”弃舒,你懂得癞埠。
不過(guò),我不把 new String("Hello, luobo");
這樣得到的對(duì)象歸于此類哈聋呢,這個(gè)我歸于下一類苗踪。
內(nèi)置對(duì)象
就是在特定的運(yùn)行環(huán)境中可以通過(guò) new XXX()
這種方式得到的對(duì)象,或者通過(guò)一定的方法可以得到削锰,但自己沒(méi)法直接創(chuàng)建的東東(如 HTMLElement通铲,沒(méi)法自己通過(guò) {...}
這樣直接聲明得到哦),當(dāng)然器贩,這個(gè)東東得像“對(duì)象”才行颅夺。
我所說(shuō)的像“對(duì)象”,其實(shí)并無(wú)“深意”磨澡。所謂的對(duì)象還不就是一個(gè)能夠保存數(shù)據(jù)碗啄,并且可選地提供了一些“方法”的東西嘛。(當(dāng)然稳摄,你有權(quán)吐槽稚字,歡迎)
普通對(duì)象
這是自己可以創(chuàng)造的,例如{ name: "luobo" }
就得到了這樣一個(gè)對(duì)象〉瑁或者通過(guò)某種方式(這里不多說(shuō)瘫想,后面再討論哈)基于自己的定義通過(guò)函數(shù)創(chuàng)造的對(duì)象,類似于:
function Person(name) {
this.name = name;
}
var me = new Person("luobo");
me.name; // "luobo"
因?yàn)檫@個(gè) Person 是自個(gè)整出來(lái)的昌讲,所以不能算是“內(nèi)置”的是吧国夜,畢竟咱們得講道理不是。然后這個(gè)對(duì)象是和你創(chuàng)造它的預(yù)期相符的短绸,你讓它有啥屬性车吹、方法,它就得有不是醋闭。所以窄驹,這么老實(shí)聽(tīng)話的,就是“普通”對(duì)象啦证逻。
函數(shù)對(duì)象
函數(shù)對(duì)象當(dāng)然是通過(guò)這種方式定義的:
function HelloWorld() {
console.log("Hello, world!");
}
這里的HelloWorld
就是個(gè)函數(shù)乐埠,多簡(jiǎn)單。
當(dāng)然囚企,也可以這樣定義函數(shù):
function () {
console.log("Hello, world!");
}
其實(shí)上面這個(gè)函數(shù)和上上面的那個(gè)其實(shí)一樣丈咐。當(dāng)然,如果你認(rèn)真看的話龙宏,會(huì)發(fā)現(xiàn)它沒(méi)有“名字”棵逊,然而這也就是沒(méi)有名字而已,函數(shù)本身已經(jīng)創(chuàng)建了烦衣,而且可以用了歹河。只不過(guò),沒(méi)有名字所以用的時(shí)候不是那么的“直白”而已花吟。你可以這樣用:
(function () {
console.log("Hello, world!");
})();
這樣就調(diào)用了秸歧,是不是很....傻啊。其實(shí)我寫過(guò)好多這樣的代碼衅澈,主要的目的不是為了定義這個(gè)函數(shù)键菱,而是為了把東西放到這個(gè)函數(shù)內(nèi)部執(zhí)行。為啥這樣呢今布?我以后講经备。(當(dāng)然,更推薦你自己看書了解啦)
函數(shù)
上面栗子中的 HelloWorld
只是個(gè)名字而已部默,你也可以把它作為一個(gè)“變量”侵蒙,這個(gè)變量的“值”就是一個(gè)函數(shù)對(duì)象啦。所以傅蹂,也可以這樣來(lái)定義函數(shù):
var HelloWorld = function () {
console.log("Hello, world!");
}
據(jù)我了解纷闺,在一些編程語(yǔ)言中(對(duì)算凿,包括Java),有“值”犁功、“引用”的說(shuō)法氓轰。在JavaScript中,不能說(shuō)就完全沒(méi)有這些東西浸卦,但是我在一些書和資料里很少看到專門討論這些的署鸡。我想還是由于一些習(xí)慣,導(dǎo)致不那么看重這些吧限嫌。例如由于閉包的存在靴庆,就會(huì)出現(xiàn)一些奇妙的現(xiàn)象,這個(gè)我也放到后面的文章再說(shuō)吧(嗯萤皂,待我再整理撒穷、積累下,畢竟閉包這種東西有些“高級(jí)”)裆熙。
還是來(lái)說(shuō)函數(shù),先說(shuō)說(shuō)函數(shù)可以被調(diào)用這件事吧禽笑。當(dāng)然入录,這是顯而易見(jiàn)的。
還是說(shuō)上面的HelloWorld
函數(shù)佳镜,可以這樣調(diào)用:HelloWorld()
僚稿,這是普通青年的做法。當(dāng)然你也可以文藝些這樣來(lái):HelloWorld.call()
蟀伸,還是會(huì)輸出結(jié)果的蚀同。但是這樣用的話,你看待HelloWorld
的視角就變了啊掏,這個(gè)時(shí)候蠢络,你就可以把它看作是一個(gè)對(duì)象,這個(gè)對(duì)象有一個(gè)方法call()
迟蜜,作用呢刹孔,就是調(diào)用你的這個(gè)函數(shù),是不是完全不一樣啦娜睛!
除了call()
髓霞,還有apply()
方法,也是可以用來(lái)調(diào)用函數(shù)的畦戒,它們的相似和不同之處方库,不在此展開(kāi)了(歡迎查資料自己了解)。通過(guò)介紹call()
障斋,貌似我再說(shuō)函數(shù)是一個(gè)對(duì)象時(shí)纵潦,就更容易理解了。當(dāng)然,還有更讓人“信服”的栗子:
HelloWorld.version = "v0.1";
嗯酪穿,這個(gè)函數(shù)還有版本啊凳干,厲害。不對(duì)被济,這個(gè)家伙還可以設(shè)置屬性救赐!不僅如此:
HelloWorld.sayHello = function () {
console.log("Hello!");
};
還可以定義方法呢。所以只磷,它當(dāng)然是個(gè)對(duì)象经磅,不過(guò)是個(gè)可以被“調(diào)用”的對(duì)象。
舉個(gè)實(shí)際中的栗子钮追,我們?cè)谟?jQuery 的時(shí)候可能都寫過(guò)類似的代碼:
$('#myDiv').css('color', 'red');
$.ajax({ url: '/foo.jsp' });
有沒(méi)有注意到预厌,上面兩行對(duì) $
的使用是不同的。第一行是直接調(diào)用$
函數(shù)(對(duì)元媚,$
就是個(gè)函數(shù))轧叽,第二行則是調(diào)用$
對(duì)象($
也是個(gè)對(duì)象哦,因?yàn)楹瘮?shù)都是對(duì)象嘛)的方法ajax
刊棕。怎么樣炭晒,是不是“茅塞頓開(kāi)”?(當(dāng)然你可能早就知道甥角,不過(guò)我之前搞清楚這個(gè)的時(shí)候可是興奮得很巴稀!)
函數(shù)生成對(duì)象
這是一個(gè)比較“高級(jí)”的話題啦(相對(duì)我來(lái)說(shuō)嗤无,不是你哈)震束,我不打算展開(kāi),因?yàn)橄朐诤竺嬷v JavaScript 中的“繼承”的時(shí)候再多說(shuō)一些当犯。先看個(gè)栗子:
function Person(name) {
return {
name: name
};
}
這里定義的函數(shù)Person
就可以生成對(duì)象垢村,怎么樣,很簡(jiǎn)單吧灶壶?
你不會(huì)打死我吧....
但是肝断,當(dāng)你看到這個(gè)的時(shí)候:
var me = new Person("luobo");
me.name; // "luobo"
你有何感想?
好了驰凛,就寫到這吧胸懈。