【21】JavaScript (函數(shù))

1 函數(shù)

1.1 什么是函數(shù)

  • 函數(shù)就是具有特定功能的代碼塊,可以被多次調(diào)用
  • 函數(shù)是 JavaScript 中的一種數(shù)據(jù)類型,屬于對(duì)象類型; 使用 typeof 判斷可以返回 function

1.2 函數(shù)的組成

  • 函數(shù)名: 函數(shù)名本質(zhì)上是個(gè)變量,函數(shù)名的命名規(guī)則與變量名的命名規(guī)則一致。
  • 參數(shù): 參數(shù)本質(zhì)上是個(gè)變量,只能在函數(shù)內(nèi)使用,在調(diào)用函數(shù)的時(shí)候才能被賦值。
  • 函數(shù)體: 用大括號(hào)包裹的代碼塊。
  • 返回值:返回值是函數(shù)的計(jì)算結(jié)果, 作為函數(shù)調(diào)用表達(dá)式的值

1.3 聲明函數(shù)

① function 關(guān)鍵字方式

function 函數(shù)名() {
    函數(shù)體語句 ...;
}

function 函數(shù)名(參數(shù)列表...) {
    函數(shù)體語句 ...;
}

② 表達(dá)式方式

var 函數(shù)名 = function() {
    函數(shù)體語句 ...;
}

var 函數(shù)名 = function(參數(shù)列表...) {
    函數(shù)體語句 ...;
}

1.4 函數(shù)調(diào)用和返回值

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

  • 函數(shù)名()才是函數(shù)調(diào)用,函數(shù)體語句才能執(zhí)行,才能得到函數(shù)的返回值。
  • 函數(shù)名后面沒有括號(hào),就是在使用一個(gè)變量,函數(shù)體語句不會(huì)執(zhí)行,也得不到函數(shù)的返回值。

② 返回值

1. 返回值是函數(shù)的計(jì)算結(jié)果,是函數(shù)調(diào)用表達(dá)式的值(函數(shù)名加括號(hào)就是函數(shù)調(diào)用表達(dá)式)
   var res = fn();    // 把函數(shù)的返回值賦值給變量 res
   fn() + 100;        // 函數(shù)的返回值與 100 相加
   console.log(fn()); // 輸出函數(shù)的返回值

2. 通過 return 關(guān)鍵字定義函數(shù)的返回值
   return 需寫在函數(shù)體內(nèi),return 右邊需寫一個(gè)表達(dá)式(變量、直接量、帶運(yùn)算符的表達(dá)式), 表達(dá)式的值就是函數(shù)的返回值。
   如果 return 右邊是空的,函數(shù)沒有返回值, 沒有返回值函數(shù)調(diào)用表達(dá)式的值會(huì)自動(dòng)得到 undefined

3. return 還可以結(jié)束函數(shù)的執(zhí)行; 一旦執(zhí)行到 return,后面的語句就不會(huì)執(zhí)行了。

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

①形參和實(shí)參

形參:函數(shù)聲明時(shí)設(shè)置的參數(shù),相當(dāng)于沒有賦值的變量,必須以變量名的形式給出。

實(shí)參:調(diào)用函數(shù)時(shí)所給的參數(shù),用于給形參賦值, 可以是變量、直接量、表達(dá)式等形式。

② 形參和實(shí)參的數(shù)量問題

標(biāo)準(zhǔn)情況下,形參和實(shí)參的數(shù)量應(yīng)一致,按順序賦值,如果:

形參數(shù)量 > 實(shí)參數(shù)量:后面的形參沒有被賦值,自動(dòng)得到 undefined。

形參數(shù)量 < 實(shí)參數(shù)量:多余的實(shí)參則沒有用。

③ 形參的默認(rèn)值(可選參數(shù))

  1. 具有默認(rèn)值的參數(shù)即可選參數(shù)
  2. 可選參數(shù)應(yīng)放在必選參數(shù)的后面,因?yàn)閷?shí)參按順序給形參賦值,不給實(shí)參則可以返回默認(rèn)值。

ES5 規(guī)范中設(shè)置默認(rèn)值的方式:

function fn(name, age) {
    // 如果 age 沒有對(duì)應(yīng)的實(shí)參, 設(shè)置一個(gè)默認(rèn)值
    if (age === undefined) {
        age = 默認(rèn)值;
    }
}

ES6 規(guī)范中的設(shè)置默認(rèn)值的方式:

funciton fn(name, age=默認(rèn)值) {
    
}

④ arguments關(guān)鍵字

  1. arguments 是系統(tǒng)定義好的變量,可以直接使用,但只能在函數(shù)內(nèi)使用, 在函數(shù)外使用則會(huì)報(bào)錯(cuò)。
  2. arguments 是個(gè)偽數(shù)組對(duì)象,里面的成員是函數(shù)調(diào)用時(shí)傳進(jìn)來的實(shí)參; arguments 具有l(wèi)ength 屬性,可以通過索引獲取到其中的每個(gè)成員。
  3. arguments 是除了形參之外另外一種獲取實(shí)參的方式。 形參只能獲取固定數(shù)量的實(shí)參,arguments 可以獲取所有的實(shí)參。
  4. 使用 arguments 可以定義可變參數(shù)數(shù)量的函數(shù)。
// 計(jì)算所有參數(shù)的和,返回結(jié)果
function sumFn() {
    // 定義變量 記錄和
    var sum = 0;
    // 遍歷 arguments
    for (var i = 0; i < arguments.length; i ++) {
        sum += arguments[i];
    }
    // 返回結(jié)果
    return sum;
}

1.6 作用域

① 變量的作用域

作用域即變量的可作用范圍,根據(jù)作用域不同,變量可分為全局變量局部變量。

全局變量: 在函數(shù)以外定義,作用域是全局。如:函數(shù)外聲明的函數(shù),函數(shù)內(nèi)沒有用var聲明的變量。

局部變量: 在函數(shù)內(nèi)定義,作用域是所在的函數(shù)。如:函數(shù)的形參,函數(shù)內(nèi)聲明的函數(shù)。

  1. 函數(shù)名本質(zhì)上是變量,所以函數(shù)本身也有作用域,由函數(shù)是在哪里聲明的決定。
  2. 如果在函數(shù)里不使用var聲明變量,該變量是全局的(嚴(yán)格模式下不允許不使用var聲明的變量的)

② 作用域鏈

函數(shù)里還可以繼續(xù)聲明函數(shù),函數(shù)的嵌套關(guān)系形成了作用域鏈,函數(shù)內(nèi)可以使用本層作用域和上層作用域中的變量。

作用域鏈描述變量查找的過程:

當(dāng)使用某個(gè)變量的時(shí)候,先從本作用域中查找,如果找不到就去上層作用域查找,哪里找到哪里停止,找不到則繼續(xù)向上查找,直到全局作用域,如果仍然沒有查找到該變量,則報(bào)錯(cuò)。

注:變量的作用域只與函數(shù)聲明的位置有關(guān)系,與函數(shù)在哪里調(diào)用無關(guān)。

1.7 變量提升

① 變量提升

  1. 代碼正式執(zhí)行之前,會(huì)進(jìn)行預(yù)解析,預(yù)解析時(shí)會(huì)把變量提升到本作用域的最前面(只創(chuàng)建了變量,卻沒有賦值)
  2. 全局變量在整個(gè)代碼正式執(zhí)行之前就發(fā)生了提升
  3. 局部變量在函數(shù)體語句執(zhí)行之前進(jìn)行提升

② 函數(shù)提升

  1. 函數(shù)名本質(zhì)上就是變量,所以函數(shù)也會(huì)提升到本作用域的最前面。
  2. 使用 function 關(guān)鍵字形式聲明的函數(shù),提升比較徹底,代碼執(zhí)行之前不但創(chuàng)建了函數(shù)名并且有值。
  3. 使用表達(dá)式方式聲明的函數(shù),提升規(guī)則與普通變量沒有差別。
  4. 函數(shù)提升與變量提升的區(qū)別:
    ① 函數(shù)提升更徹底
    ② 正式執(zhí)行代碼的時(shí)候,執(zhí)行到變量聲明并賦值的語句會(huì)進(jìn)行賦值操作, 執(zhí)行到函數(shù)聲明語句會(huì)跳過

1.8 匿名函數(shù)

即沒有名字的函數(shù),用函數(shù)這種數(shù)據(jù)類型的直接量表示,適合作為自調(diào)用函數(shù)回調(diào)函數(shù)

1.9 自調(diào)用函數(shù)(立即執(zhí)行的函數(shù))

函數(shù)聲明完立即被調(diào)用,主要作用是用來產(chǎn)生作用域,避免全局變量污染。一般以匿名函數(shù)作為自調(diào)用函數(shù),有名字的函數(shù)也可以作為自調(diào)用函數(shù),但沒有必要。

// 匿名的自調(diào)用函數(shù)(立即執(zhí)行的函數(shù))
(function() {
    函數(shù)體語句;
})();

// 有名字的自調(diào)用函數(shù)
(function fn() {
    函數(shù)體語句;
})();

// 匿名的自調(diào)用函數(shù) 設(shè)置參數(shù)
(function(形參1, 形參2) {
    函數(shù)體語句;
})(實(shí)參1, 實(shí)參2);

1.10 回調(diào)函數(shù)

具有以下三個(gè)條件的函數(shù)稱為回調(diào)函數(shù):

  • ① 函數(shù)是我定義的
  • ② 我沒有直接調(diào)用該函數(shù)
  • ③ 函數(shù)卻執(zhí)行了

注意: 回調(diào)函數(shù)大部分情況會(huì)作為其他函數(shù)(或方法)的參數(shù)。

1.11 遞歸函數(shù)

函數(shù)內(nèi)部再次調(diào)用自己。

① 遞歸成功的條件:

  • 有明確的結(jié)束遞歸的條件
  • 有一個(gè)趨向于結(jié)束遞歸調(diào)用的趨勢(shì)

② 遞歸函數(shù)的缺點(diǎn)

  • 可能發(fā)生內(nèi)存泄漏
  • 效率不高

③ 遞歸函數(shù)應(yīng)用場(chǎng)景

  • 后端的目錄操作(刪除、復(fù)制、剪切)
  • 前端對(duì)后端數(shù)據(jù)進(jìn)行遞歸處理
?著作權(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ù)。

相關(guān)閱讀更多精彩內(nèi)容

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