函數(shù)

函數(shù)的聲明

JavaScript中函數(shù)使用 function 關(guān)鍵字聲明

匿名函數(shù)的聲明

匿名函數(shù)聲明語法:

function (函數(shù)的參數(shù)){ 函數(shù)塊 }
只聲明匿名函數(shù)的代碼是不正確的

 function a(){}


匿名函數(shù)經(jīng)常被用作回調(diào)函數(shù)盟迟。
緊接著匿名函數(shù)聲明后"}"的調(diào)用是不正確的,例如下面的代碼

 function a(){}()

函數(shù)聲明其實(shí)是語句潦闲,但是當(dāng)函數(shù)聲明在表達(dá)式位置(右值)時队萤,函數(shù)聲明便可成為表達(dá)式(在非匿名函數(shù)命名處有例子)。
可以使用一些黑魔法("()"矫钓、","要尔、"!")把函數(shù)聲明轉(zhuǎn)換為表達(dá)式舍杜,其返回值是被聲明的函數(shù)。
以下的代碼都是正確的

> (function () {
...    console.log('Hello,world');
...})()

Hello,world
< undefined    //匿名函數(shù)的返回值(如果沒有返回值則為undefined)
>(function () {
...   console.log('Hello,world');
...}())

Hello,world
< undefined    //匿名函數(shù)的返回值(如果沒有返回值則為undefined)
> 1, function () {
...    console.log('Hello,world');
...})()

Hello,world
< undefined
> !function () {
...    console.log('Hello,world');
...})

Hello,world
< undefined
原因猜測(以下純屬瞎猜赵辕,有錯隨意懟我):

要解釋這個問題既绩,首先需要介紹JavaScript某個特性——Automatic Semicolon Insertion(ASI,自動分號插入機(jī)制)(ES6規(guī)范)

ASI

為了書寫方便还惠,在某些情況下作為語句結(jié)束的標(biāo)志——";”可以省略不寫饲握,而在解釋時被自動添加(其實(shí)也不添加";",只是解釋器 "正確" 理解了在此處就是語句的結(jié)束)蚕键。
解釋器也不是隨意插入";"的救欧,但是是基于以下這兩點(diǎn)的:
1.以換行為基礎(chǔ)。
2.解析器會盡量將新行并入當(dāng)前行锣光,當(dāng)且僅當(dāng)符合 ASI規(guī)則 且不符合 No ASI規(guī)則 時才會將新行視為獨(dú)立的語句笆怠。

ASI規(guī)則

1.新行并入當(dāng)前行將構(gòu)成非法語句,自動插入分號誊爹。
2.在continue,return,break,throw后自動插入分號蹬刷。
3.++、--后綴表達(dá)式作為新行的開始频丘,在行首自動插入分號办成。

No ASI規(guī)則

1.新行以"("開始
1.新行以"["開始
1.新行以"/"開始
1.新行以"+"、"-"搂漠、"%"迂卢、"*"開始
1.新行以","或"."開始

匿名函數(shù)聲明本來是表達(dá)式,但是由于 ASI 桐汤,自動給"}"末尾加了個";"(雖然好像并不符合 ASI規(guī)則), 就被解釋為語句而克。
根據(jù)No ASI規(guī)則就可以反制因?yàn)?ASI 造成"}"末尾加了個";"的情況。
ASI在后面出場率比較高惊科,因?yàn)檫@個特性(duliu)可以背很多鍋(沒錯,我是寫分號黨的人)亮钦。


(官方正經(jīng)的解釋在這兒)

非匿名函數(shù)的聲明

非匿名函數(shù)聲明語法:

function 函數(shù)名 (函數(shù)的參數(shù)) { 函數(shù)塊 }
非匿名函數(shù)聲明后不可以緊接著 "}"進(jìn)行函數(shù)調(diào)用馆截。
下面的代碼是不正確的

function a(){
    console.log("Hello,world")
}()

下面的例子雖然沒有語法錯誤,但是并沒有調(diào)用 a 函數(shù)蜂莉,因?yàn)?(1) 沒有解釋為函數(shù)調(diào)用蜡娶,而被解釋為將 1 轉(zhuǎn)換為表達(dá)式

function a(a){
  console.log("Hello,world")
}(1)

函數(shù)的命名

函數(shù)命名規(guī)則遵從變量和常量命名規(guī)則(小寫駝峰法)。
函數(shù)和變量不能取相同的名稱映穗,否則同名變量會被覆蓋窖张。

其實(shí)函數(shù)聲明是特殊的變量聲明,任何函數(shù)聲明都可以轉(zhuǎn)換為將一個匿名函數(shù)賦值給函數(shù)名同名變量蚁滋。
例如以下代碼等價:

function a(){}

var a = function(){}

此時匿名函數(shù)聲明出現(xiàn)在了表達(dá)式位置宿接,但是很奇怪的是第二種聲明語法并沒有返回值赘淮。
所有的函數(shù)聲明都由 var 關(guān)鍵字聲明,因此所有函數(shù)聲明都會被JavaScript提前睦霎。
且若有同名變量則會因重復(fù)聲明而被覆蓋梢卸。
同時也說明兩個函數(shù)不能有相同的函數(shù)名(函數(shù)其實(shí)就是特殊的變量),
也就是說JavaScript不支持重載副女,JavaScript只通過函數(shù)名來判斷兩個函數(shù)是否是同一個函數(shù)而不檢查函數(shù)簽名蛤高。

函數(shù)的參數(shù)

函數(shù)的參數(shù)可以為0個或多個。
若為0個則留空即可碑幅。例如 function a(){} 就聲明了一個沒有參數(shù)的函數(shù)戴陡。
若為1個以上則不同參數(shù)之間要用 , 分割。
例如以下代碼聲明了帶有多個參數(shù)的函數(shù)

function a(b, c, d, e, f){}

與強(qiáng)類型語言不同沟涨,弱類型語言在聲明函數(shù)時不需要指明函數(shù)參數(shù)類型
這是弱類型語言與強(qiáng)類型語言很不同的一點(diǎn)恤批。

函數(shù)的調(diào)用

1.函數(shù)/方法調(diào)用模式:
函數(shù)名(傳遞的參數(shù))
2.構(gòu)造器調(diào)用模式
new 函數(shù)名(傳遞的參數(shù))
傳遞的參數(shù)語法與函數(shù)的參數(shù)語法相同,在此不再贅述拷窜。
當(dāng)傳遞參數(shù)的個數(shù)與聲明不匹配時开皿,按照以下方式處理:
1.傳遞參數(shù)個數(shù)大于聲明參數(shù)個數(shù): 忽略多余傳遞參數(shù)(但會去計算)。
例如:

> function a(a){
... console.log(a);    
...}
< undefined
> var b = 1;
< 1 //賦值語句的返回值
> a(b, b++, ++b)
1 //b在自增前的值
< undefined
> b
< 3 //b經(jīng)過兩次自增后的值

2.傳遞參數(shù)個數(shù)小于聲明參數(shù)個數(shù): 剩余聲明參數(shù)的值全部為 undefined篮昧。

arguments變量

除了在函數(shù)中聲明的形參外你會得到一個"免費(fèi)配送的" arguments 變量(即使函數(shù)沒有形參但 arguments 依然存在)赋荆。
你可以通過 arguments.length 得到傳遞參數(shù)的個數(shù)。你也可以通過 arguments[i] 來獲取每一個參數(shù)懊昨。

arguments 看起來像一個數(shù)組窄潭,其實(shí)不是一個數(shù)組,它是一個屬性名稱為從 0 到 arguments.length - 1的對象(這個特殊的對象我們將在對象詳細(xì)研究)酵颁。
以下代碼便可說明問題:

> function a(){
...console.log(arguments);
...}
< undefined
> a(1, 2, 3, 4, 5, 6, 7)
{ '0': 1, '1': 2, '2': 3, '3': 4, '4': 5, '5': 6, '6': 7 }
< undefined

arguments 不是關(guān)鍵字嫉你,因此它可以被同名變量、常量或函數(shù)覆蓋躏惋,
甚至你可以給它賦值(但是 arguments 不會改變幽污,這個現(xiàn)象會在對象解釋)。
如果函數(shù)確實(shí)有形參且你改變了形參的值簿姨,相應(yīng)的變化會追蹤到 arguments中距误。
但在 嚴(yán)格模式 下,"arguments" 不能作為變量扁位、常量或函數(shù)的名稱准潭,且形參的變化不會追蹤到 arguments 中。
arguments 的MDN文檔在這里域仇。

函數(shù)中的this

函數(shù)中可以使用 this 關(guān)鍵字獲得特定的對象刑然,根據(jù)函數(shù)調(diào)用方式的不同,this 指向的對象也不盡相同暇务。

  1. 方法調(diào)用模式:
    當(dāng)一個函數(shù)被保存為對象的一個屬性時泼掠,我們稱它為一個方法怔软。
    當(dāng)一個方法被調(diào)用時,this被綁定到該對象(這種調(diào)用模式將會在對象詳細(xì)介紹)武鲁。

  2. 函數(shù)調(diào)用模式:
    當(dāng)一個函數(shù)并非一個對象的屬性時爽雄,那么它就是被當(dāng)作一個函數(shù)來調(diào)用的。以此模式調(diào)用函數(shù)時沐鼠,this 被綁定到全局對象挚瘟。
    嚴(yán)格模式調(diào)用時,this 如果是全局變量則會被賦值為 null饲梭。

改變函數(shù)中 this所指對象的方法

這里的方法指的是Function原型的方法乘盖,函數(shù)其實(shí)也是特殊的對象。

  1. apply 方法:
    apply 方法的函數(shù)簽名為 apply(thisArg, [argArray])
    其中 thisArg 是在函數(shù)內(nèi)代替 this 的對象憔涉,argArray 是給函數(shù)傳遞的參數(shù)订框。
    apply 方法的返回值為函數(shù)調(diào)用后的返回值。
    apply 的MDN文檔在這里兜叨。

  2. call 方法:
    call 方法的函數(shù)簽名為 call(thisArg[, arg1[, arg2[, ...]]])
    其中 thisArg 是在函數(shù)內(nèi)代替 this 的對象穿扳,arg1arg2国旷、...是給函數(shù)傳遞的參數(shù)矛物。
    call 方法的返回值為函數(shù)調(diào)用后的返回值。
    call 的MDN文檔在這里跪但。

  3. bind 方法:
    bind 方法的函數(shù)簽名為 bind(thisArg[, arg1[, arg2[, ...]]])
    其中 thisArg 是在函數(shù)內(nèi)代替 this 的對象履羞,arg1arg2屡久、...是給函數(shù)傳遞的參數(shù)忆首。
    bind 方法的返回值是一個新的函數(shù),在函數(shù)體內(nèi) this 指向 thisArg 對象被环。
    bind 的MDN文檔在這里糙及。

從函數(shù)中返回

使用 return 關(guān)鍵字就可以返回函數(shù)的值。
語法: return 返回值

注意: JavaScript中函數(shù)只能擁有一個返回值筛欢,函數(shù)一經(jīng)返回就立即跳出函數(shù)體浸锨。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市悴能,隨后出現(xiàn)的幾起案子揣钦,更是在濱河造成了極大的恐慌雳灾,老刑警劉巖漠酿,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異谎亩,居然都是意外死亡蔗候,警方通過查閱死者的電腦和手機(jī)有决,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進(jìn)店門频蛔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人浑劳,你說我怎么就攤上這事∝舶瑁” “怎么了魔熏?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長鸽扁。 經(jīng)常有香客問我蒜绽,道長,這世上最難降的妖魔是什么桶现? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任躲雅,我火速辦了婚禮,結(jié)果婚禮上骡和,老公的妹妹穿的比我還像新娘相赁。我一直安慰自己,他們只是感情好慰于,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布钮科。 她就那樣靜靜地躺著,像睡著了一般东囚。 火紅的嫁衣襯著肌膚如雪跺嗽。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天页藻,我揣著相機(jī)與錄音桨嫁,去河邊找鬼。 笑死份帐,一個胖子當(dāng)著我的面吹牛璃吧,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播废境,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼畜挨,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了噩凹?” 一聲冷哼從身側(cè)響起巴元,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎驮宴,沒想到半個月后逮刨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡堵泽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年修己,在試婚紗的時候發(fā)現(xiàn)自己被綠了恢总。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡睬愤,死狀恐怖片仿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情尤辱,我是刑警寧澤砂豌,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站光督,受9級特大地震影響奸鸯,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜可帽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一娄涩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧映跟,春花似錦蓄拣、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至荸镊,卻和暖如春咽斧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背躬存。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工张惹, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人岭洲。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓宛逗,卻偏偏與公主長得像,于是被迫代替她去往敵國和親盾剩。 傳聞我的和親對象是個殘疾皇子雷激,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 函數(shù)和對象 1、函數(shù) 1.1 函數(shù)概述 函數(shù)對于任何一門語言來說都是核心的概念告私。通過函數(shù)可以封裝任意多條語句屎暇,而且...
    道無虛閱讀 4,564評論 0 5
  • 函數(shù)只定義一次,但可能被執(zhí)行或調(diào)用任意次驻粟。JS函數(shù)是參數(shù)化的根悼,函數(shù)的定義會包括一個稱為形參的標(biāo)識符列表,這些參數(shù)在...
    PySong閱讀 853評論 0 0
  • 函數(shù)只定義一次,但可能被執(zhí)行或調(diào)用任意次番挺。JS函數(shù)是參數(shù)化的,函數(shù)的定義會包括一個稱為形參的標(biāo)識符列表屯掖,這些參數(shù)在...
    PySong閱讀 526評論 0 0
  • 函數(shù)只定義一次玄柏,但可能被執(zhí)行或調(diào)用任意次。JS函數(shù)是參數(shù)化的贴铜,函數(shù)的定義會包括一個稱為形參的標(biāo)識符列表粪摘,這些參數(shù)在...
    PySong閱讀 319評論 0 0
  • MSE和CE是機(jī)器學(xué)習(xí)中常見的兩種損失函數(shù)徘意,在訓(xùn)練神經(jīng)網(wǎng)絡(luò)中,也經(jīng)常用到轩褐,但是如何深刻地理解二者的異同椎咧,卻不是容易...
    工程師milter閱讀 11,688評論 18 27