細(xì)論函數(shù)

一、函數(shù)的本質(zhì)

重點(diǎn):函數(shù)是對(duì)象,函數(shù)名是指針
函數(shù)是Function引用類型的實(shí)例,函數(shù)實(shí)際也是一個(gè)對(duì)象。
我們可以用下面這種并不常見也不推薦的方式來創(chuàng)建一個(gè)函數(shù),來直觀理解:

var fun = new Function("n1", "n2", "return n1 + n2")
執(zhí)行結(jié)果

因此這里有一個(gè)很重要的點(diǎn):函數(shù)名就是指向函數(shù)對(duì)象的一個(gè)指針而已。
由此可以得到的引生有很多:比如一個(gè)函數(shù)可以有多個(gè)名字,都是指向同一個(gè)函數(shù)內(nèi)存位置。
如下面例子:sum和another都是指向同一個(gè)函數(shù),即使sum設(shè)置為null后,也不影響another的執(zhí)行。
重點(diǎn):不帶圓括號(hào)的函數(shù)名是訪問函數(shù)指針而已,而非調(diào)用函數(shù)。函數(shù)名后加括號(hào)才是真正的調(diào)用函數(shù)。


例子截圖

因?yàn)楹瘮?shù)名只是指針的這個(gè)特性,顯而易見的,使用同一個(gè)函數(shù)名的兩個(gè)函數(shù),第二個(gè)函數(shù)是會(huì)覆蓋第一個(gè)函數(shù)的。


覆蓋實(shí)例

二、函數(shù)的定義

1、上述舉例的Function構(gòu)造函數(shù)(不常用,用于定義理解就行)
2、函數(shù)聲明

funtion sum (a,b) {
  return a+b
}

3、函數(shù)表達(dá)式

var sum = function (a,b) {
  return a+b
};

例子中為變量sum初始化了一個(gè)函數(shù),此時(shí)不必要為函數(shù)給個(gè)命名了,因?yàn)橥ㄟ^變量sum就指向這個(gè)函數(shù)了。

重點(diǎn):兩者的區(qū)別,函數(shù)聲明方式,JavaScript在解析代碼時(shí),會(huì)將所有這種定義方式的函數(shù)進(jìn)行提升,因此執(zhí)行語(yǔ)句在定義前書寫也是沒有問題的。而函數(shù)表達(dá)式是執(zhí)行到代碼所在位置才會(huì)解析。因此不能提前使用函數(shù)表達(dá)式定義的變量


兩者調(diào)用順序區(qū)別

三、函數(shù)的應(yīng)用

高階函數(shù):函數(shù)名作為一個(gè)存儲(chǔ)的是指向函數(shù)的指針位置的變量,因此大可將函數(shù)作為一個(gè)參數(shù)傳給另一個(gè)函數(shù),也可以將一個(gè)函數(shù)作為另一個(gè)函數(shù)的返回結(jié)果。
有一個(gè)典型的應(yīng)用就是sort方法中傳入比較大小的函數(shù)作為參數(shù),來指定排序順序是升序還是降序:
sort方法的默認(rèn)排序是會(huì)將數(shù)組中元素轉(zhuǎn)化為字符串之后Unicode位點(diǎn)進(jìn)行排序的,所以對(duì)于數(shù)字的排序,需要特地指定一個(gè)排序函數(shù)compareFunction給它。


指定和不指定排序函數(shù)的對(duì)比

如果 compareFunction(a, b) 小于 0 ,那么 a 會(huì)被排列到 b 之前;
如果 compareFunction(a, b) 等于 0 , a 和 b 的相對(duì)位置不變。
如果 compareFunction(a, b) 大于 0 , b 會(huì)被排列到 a 之前。
因此,對(duì)于數(shù)字的升序,可以直接通過相減來指定:

[12,21,3,45].sort((a,b)=>a-b)   //升序

[12,21,3,45].sort((a,b)=>b-a)  //降序 

此處一次說明array的sort方法內(nèi)部執(zhí)行判斷過程:

var items = [
  { name: 'Edward', value: 21 },
  { name: 'Sharpe', value: 37 },
  { name: 'And', value: 45 },
  { name: 'The', value: -12 },
  { name: 'Magnetic',value: 10 },
  { name: 'Zeros', value: 37 }
];

// sort by value
items.sort(function (a, b) {
  console.log(a,b)
  return (a.value - b.value)
});

執(zhí)行結(jié)果:


sort執(zhí)行結(jié)果

通過將sort執(zhí)行過程給打印出來,發(fā)現(xiàn)執(zhí)行判斷過程是:
按照數(shù)據(jù)數(shù)據(jù)順序,優(yōu)先比較21和37,得到37大,比較37和45,得到45大,則順著比較45和-12,比較結(jié)果-12比較小,則需要確定-12和37、21分別的大小,判斷完這塊得到-12比37和21都小,就將-12移到21前面,然后接著回來繼續(xù)比較45和下一個(gè)數(shù)10的大小....確定10比較小,則需要為10安插位置,就重復(fù)前面的步驟,持續(xù)將10與45之前的大小進(jìn)行比較,直至遇到比10小的數(shù)字-12,安插好10的位置,然后繼續(xù)比較目前位置的最大數(shù)45與下一個(gè)順序數(shù)字的大小,以此循環(huán)直至數(shù)組結(jié)束。

四、函數(shù)的內(nèi)部屬性

1、this
一句話說this就是函數(shù)執(zhí)行時(shí)的環(huán)境對(duì)象。此處this在不用場(chǎng)景下的區(qū)分見之前的文章。
2、argument
argument是偽數(shù)組對(duì)象,擁有l(wèi)enth屬性

五、函數(shù)的屬性和方法

最為重要的就是call、apply、bind這三個(gè)方法。
其實(shí)每次直接使用大括號(hào)執(zhí)行函數(shù),是call方法的閹割使用版本。
我們大可以直接使用call方法來擴(kuò)充函數(shù)執(zhí)行的作用域,指定第一個(gè)參數(shù)為this。
注意如果使用call的時(shí)候,不想指定this,一定要記得寫上undefined來占位
具體這三個(gè)方法的區(qū)別之前的文章有細(xì)述。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容