- 我們代碼里面所說的函數(shù)和我們上學的時候學習的什么三角函數(shù)、二次函數(shù)之類的不是一個東西
函數(shù)的概念
對于
js來說,函數(shù)就是把任意一段代碼放在一個 盒子 里面在我想要讓這段代碼執(zhí)行的時候,直接執(zhí)行這個 盒子 里面的代碼就行
-
先看一段代碼
// 這個是我們以前寫的一段代碼 for (var i = 0; i < 10; i++) { console.log(i) } // 函數(shù),這個 {} 就是那個 “盒子” function fn() { // 這個函數(shù)我們以前寫的代碼 for (var i = 0; i < 10; i++) { console.log(i) } }
函數(shù)的兩個階段(重點)
- 按照我們剛才的說法,兩個階段就是 放在盒子里面 和 讓盒子里面的代碼執(zhí)行
函數(shù)定義階段
定義階段就是我們把代碼 放在盒子里面
我們就要學習怎么 放進去,也就是書寫一個函數(shù)
我們有兩種定義方式 聲明式 和 賦值式
聲明式
使用
function這個關鍵字來聲明一個函數(shù)-
語法:
function fn() { // 一段代碼 } // function: 聲明函數(shù)的關鍵字,表示接下來是一個函數(shù)了 // fn: 函數(shù)的名字,我們自己定義的(遵循變量名的命名規(guī)則和命名規(guī)范) // (): 必須寫,是用來放參數(shù)的位置(一會我們再聊) // {}: 就是我們用來放一段代碼的位置(也就是我們剛才說的 “盒子”)
賦值式
其實就是和我們使用
var關鍵字是一個道理了首先使用
var定義一個變量,把一個函數(shù)當作值直接賦值給這個變量就可以了-
語法:
var fn = function () { // 一段代碼 } // 不需要在 function 后面書寫函數(shù)的名字了,因為在前面已經(jīng)有了
函數(shù)調用階段
- 就是讓 盒子里面 的代碼執(zhí)行一下
- 讓函數(shù)執(zhí)行
- 兩種定義函數(shù)的方式不同,但是調用函數(shù)的方式都以一樣的
調用一個函數(shù)
-
函數(shù)調用就是直接寫
函數(shù)名()就可以了// 聲明式函數(shù) function fn() { console.log('我是 fn 函數(shù)') } // 調用函數(shù) fn() // 賦值式函數(shù) var fn2 = function () { console.log('我是 fn2 函數(shù)') } // 調用函數(shù) fn()- 注意: 定義完一個函數(shù)以后,如果沒有函數(shù)調用,那么寫在 {} 里面的代碼沒有意義,只有調用以后才會執(zhí)行
調用上的區(qū)別
雖然兩種定義方式的調用都是一樣的,但是還是有一些區(qū)別的
-
聲明式函數(shù): 調用可以在 定義之前或者定義之后
// 可以調用 fn() // 聲明式函數(shù) function fn() { console.log('我是 fn 函數(shù)') } // 可以調用 fn() -
賦值式函數(shù): 調用只能在 定義之前
// 會報錯 fn() // 賦值式函數(shù) var fn = function () { console.log('我是 fn 函數(shù)') } // 可以調用 fn()
強化練習
- 編寫一個函數(shù),計算兩個數(shù)字的和、差、積、商
要求:使用傳參的形式 - 編寫一個函數(shù),傳遞三個不同的整數(shù),
- 判斷哪個數(shù)字最大,哪個數(shù)字最小,哪個數(shù)組在中間
- 在控制臺輸出
函數(shù)的參數(shù)(重點)
我們在定義函數(shù)和調用函數(shù)的時候都出現(xiàn)過
()現(xiàn)在我們就來說一下這個
()的作用就是用來放參數(shù)的位置
-
參數(shù)分為兩種 形參 和 實參
// 聲明式 function fn(形參寫在這里) { // 一段代碼 } fn(實參寫在這里) // 賦值式函數(shù) var fn = function (形參寫在這里) { // 一段代碼 } fn(實參寫在這里)
形參和實參的作用
-
形參
就是在函數(shù)內部可以使用的變量,在函數(shù)外部不能使用
每寫一個單詞,就相當于在函數(shù)內部定義了一個可以使用的變量(遵循變量名的命名規(guī)則和命名規(guī)范)
-
多個單詞之間以
,分隔// 書寫一個參數(shù) function fn(num) { // 在函數(shù)內部就可以使用 num 這個變量 } var fn1 = function (num) { // 在函數(shù)內部就可以使用 num 這個變量 } // 書寫兩個參數(shù) function fun(num1, num2) { // 在函數(shù)內部就可以使用 num1 和 num2 這兩個變量 } var fun1 = function (num1, num2) { // 在函數(shù)內部就可以使用 num1 和 num2 這兩個變量 } 如果只有形參的話,那么在函數(shù)內部使用的值個變量是沒有值的,也就是
undefined形參的值是在函數(shù)調用的時候由實參決定的
-
實參
在函數(shù)調用的時候給形參賦值的
-
也就是說,在調用的時候是給一個實際的內容的
function fn(num) { // 函數(shù)內部可以使用 num } // 這個函數(shù)的本次調用,書寫的實參是 100 // 那么本次調用的時候函數(shù)內部的 num 就是 100 fn(100) // 這個函數(shù)的本次調用,書寫的實參是 200 // 那么本次調用的時候函數(shù)內部的 num 就是 200 fn(200) 函數(shù)內部的形參的值,由函數(shù)調用的時候傳遞的實參決定
-
多個參數(shù)的時候,是按照順序一一對應的
function fn(num1, num2) { // 函數(shù)內部可以使用 num1 和 num2 } // 函數(shù)本次調用的時候,書寫的參數(shù)是 100 和 200 // 那么本次調用的時候,函數(shù)內部的 num1 就是 100,num2 就是 200 fn(100, 200)
參數(shù)個數(shù)的關系
-
形參比實參少
因為是按照順序一一對應的
-
形參少就會拿不到實參給的值,所以在函數(shù)內部就沒有辦法用到這個值
function fn(num1, num2) { // 函數(shù)內部可以使用 num1 和 num2 } // 本次調用的時候,傳遞了兩個實參,100 200 和 300 // 100 對應了 num1,200 對應了 num2,300 沒有對應的變量 // 所以在函數(shù)內部就沒有辦法依靠變量來使用 300 這個值 fn(100, 200, 300)
-
形參比實參多
因為是按照順序一一對應的
-
所以多出來的形參就是沒有值的,就是
undefinedfunction fn(num1, num2, num3) { // 函數(shù)內部可以使用 num1 num2 和 num3 } // 本次調用的時候,傳遞了兩個實參,100 和 200 // 就分別對應了 num1 和 num2 // 而 num3 沒有實參和其對應,那么 num3 的值就是 undefined fn(100, 200)
函數(shù)的return(重點)
-
return返回的意思,其實就是給函數(shù)一個 返回值 和 終斷函數(shù)
終斷函數(shù)
當我開始執(zhí)行函數(shù)以后,函數(shù)內部的代碼就會從上到下的依次執(zhí)行
必須要等到函數(shù)內的代碼執(zhí)行完畢
-
而
return關鍵字就是可以在函數(shù)中間的位置停掉,讓后面的代碼不在繼續(xù)執(zhí)行function fn() { console.log(1) console.log(2) console.log(3) // 寫了 return 以后,后面的 4 和 5 就不會繼續(xù)執(zhí)行了 return console.log(4) console.log(5) } // 函數(shù)調用 fn()
返回值
函數(shù)調用本身也是一個表達式,表達式就應該有一個值出現(xiàn)
-
現(xiàn)在的函數(shù)執(zhí)行完畢之后,是不會有結果出現(xiàn)的
// 比如 1 + 2 是一個表達式,那么 這個表達式的結果就是 3 console.log(1 + 2) // 3 function fn() { // 執(zhí)行代碼 } // fn() 也是一個表達式,這個表達式就沒有結果出現(xiàn) console.log(fn()) // undefined -
return關鍵字就是可以給函數(shù)執(zhí)行完畢一個結果function fn() { // 執(zhí)行代碼 return 100 } // 此時,fn() 這個表達式執(zhí)行完畢之后就有結果出現(xiàn)了 console.log(fn()) // 100- 我們可以在函數(shù)內部使用
return關鍵把任何內容當作這個函數(shù)運行后的結果
- 我們可以在函數(shù)內部使用
函數(shù)的優(yōu)點
- 函數(shù)就是對一段代碼的封裝,在我們想調用的時候調用
- 函數(shù)的幾個優(yōu)點
- 封裝代碼,使代碼更加簡潔
- 復用,在重復功能的時候直接調用就好
- 代碼執(zhí)行時機,隨時可以在我們想要執(zhí)行的時候執(zhí)行
預解析(重點)
-
預解析 其實就是聊聊
js代碼的編譯和執(zhí)行 -
js是一個解釋型語言,就是在代碼執(zhí)行之前,先對代碼進行通讀和解釋,然后在執(zhí)行代碼 - 也就是說,我們的
js代碼在運行的時候,會經(jīng)歷兩個環(huán)節(jié) 解釋代碼 和 執(zhí)行代碼
解釋代碼
因為是在所有代碼執(zhí)行之前進行解釋,所以叫做 預解析(預解釋)
-
需要解釋的內容有兩個
- 聲明式函數(shù)
- 在內存中先聲明有一個變量名是函數(shù)名,并且這個名字代表的內容是一個函數(shù)
-
var關鍵字- 在內存中先聲明有一個變量名
- 聲明式函數(shù)
-
看下面一段代碼
fn() console.log(num) function fn() { console.log('我是 fn 函數(shù)') } var num = 100 -
經(jīng)過預解析之后可以變形為
function fn() { console.log('我是 fn 函數(shù)') } var num fn() console.log(num) num = 100 賦值式函數(shù)會按照
var關鍵字的規(guī)則進行預解析
強化練習2
編寫任意個數(shù)字的求和、差、積、商的函數(shù)
編寫生成4位數(shù)字驗證碼的函數(shù),并生成10次
提示:使用Math.random()函數(shù)可以產(chǎn)生(0-1 ]之間的隨機小數(shù)
強化練習3
- 編寫一個函數(shù),計算任意兩個數(shù)字之間所能組成的奇數(shù)個數(shù),數(shù)字必須是個位數(shù)
比如: 計算0-3之間能組成的奇數(shù)個是01、03、11、13、21、23、31、33 - 某個公司采用公用電話傳遞數(shù)據(jù),數(shù)據(jù)是四位的整數(shù),在傳遞過程中是加密的,加密規(guī)則如下:每位數(shù)字都加上5,然后用除以10的余數(shù)代替該數(shù)字,再將第一位和第四位交換,第二位和第三位交換,請編寫一個函數(shù),傳入原文,輸出密文