JavaScript-函數(shù)

函數(shù)的定義語法

function 函數(shù)名(){
    代碼段
}

function是一個關(guān)鍵字庇麦,函數(shù)的名字自定義放典,但取名的規(guī)則和變量定義的規(guī)則相同。定義好的函數(shù)并不會自己執(zhí)行钝荡,而是需要我們進行調(diào)用。

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

語法:
函數(shù)名()

舉例:

// 定義函數(shù):求兩個數(shù)的和
function fn(){
    var a = 1;
    var b = 2;
    var c = a + b;
    console.log(c);
}
// 函數(shù)定義好以后舶衬,不會自動執(zhí)行埠通,需要手動調(diào)用
fn();

賦值式函數(shù)

將一個函數(shù)代碼段賦值給一個變量,這個變量的類型是function類型,變量的值為函數(shù)的代碼逛犹,可以正常的調(diào)用端辱,但如果給他賦值的函數(shù)是有名稱的,那么這個函數(shù)名稱失效(調(diào)用后報錯 函數(shù)名 is not defined)一般可以在賦值時省略這個名稱虽画。
例子:

    var a = function zhubi() {
        console.log('zhubiluohuihuang');
    }
    a();
    console.log(a);
    console.log(typeof a);
    zhubi()

控制臺查看結(jié)果如下:


賦值式函數(shù)

匿名函數(shù)

沒有名字的函數(shù)叫做匿名函數(shù)舞蔽。匿名函數(shù)在空間中不能單獨的存在,必須用小括號將它包裹码撰。

(function(){
    console.log(13)
})

匿名函數(shù)用一種特殊的方式調(diào)用渗柿,引出了新的概念,自調(diào)用函數(shù)脖岛。

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

調(diào)用匿名函數(shù)的語法:

(function(){
    console.log(13)
})()

這樣的函數(shù)在定義好后被立即調(diào)用朵栖,同時自調(diào)用函數(shù)還有兩種不同調(diào)用的寫法,不給函數(shù)加小括號而是改用~柴梆!

!function(){
    console.log(14);
}()

~function(){
    console.log(14);
}()

PS:自調(diào)用的函數(shù)也可以傳遞參數(shù)陨溅。

(function(a,b){
    var c = a + b;
    document.write(c);
})(1,2);

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

在函數(shù)中的變量需要根據(jù)需要發(fā)生變化時绍在,就可以定義帶參數(shù)的函數(shù)门扇。形參聲明的方法將變量寫在定義函數(shù)的()中,多個變量用,隔開偿渡。
例如:

function zizeng(a){  // 叫做形參 - 形式上的參數(shù)
    var b = a + 1;
    console.log(b);
}

調(diào)用時臼寄,需要給形參賦值,在調(diào)用的()中從左到右一一對應(yīng)的寫入需要付給形參的值溜宽,這些值被稱為實參脯厨。

zizeng(1); // 實參 - 實際上的參數(shù),實參其實就是給形參賦值

如果沒有實參給形參賦值坑质,形參默認(rèn)是undefined合武,如果實參數(shù)量超出了形參临梗,超出的實參是無效的

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

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

當(dāng)我們?nèi)フ{(diào)用函數(shù)的時候,通過函數(shù)的名稱就可以調(diào)用到稼跳,那說明我們在定義函數(shù)的時候盟庞,函數(shù)就已經(jīng)保存起來了,所以下面才能調(diào)用出來汤善。
調(diào)用函數(shù)什猖,就相當(dāng)于將這段代碼拿出來執(zhí)行。

函數(shù)的優(yōu)點

  1. 實現(xiàn)了代碼的可重用性
  2. 實現(xiàn)了模塊化編程

帶返回值的函數(shù)

如果我們需要一個函數(shù)調(diào)用之后得到的結(jié)果红淡,就需要帶返回值的函數(shù)不狮。返回函數(shù)的結(jié)果,在函數(shù)中使用return關(guān)鍵字在旱,后面跟上要返回的結(jié)果摇零,可以使一個變量也可以是其他。
例如:

    function zhubi(a, b) {
        var c;
        c = a + b;
        return c;//返回c為函數(shù)計算的結(jié)果
    }
    var d = zhubi(3,5) * 4;//執(zhí)行這里的計算需要return的到函數(shù)計算的結(jié)果
    console.log(d);//返回結(jié)果為32

return關(guān)鍵字除了可以給函數(shù)調(diào)用返回結(jié)果桶蝎,還可以結(jié)束函數(shù)運行

結(jié)束運行

雖然在函數(shù)中有一個字符串輸出的代碼驻仅,但因為return結(jié)束了函數(shù)的進程,所以代碼并沒有被輸出登渣。

return只能返回一個結(jié)果噪服,不能返回多個

若函數(shù)中沒有加return胜茧,那么函數(shù)的返回值是undefined粘优,而如果加了return而return后面沒有數(shù)值,函數(shù)返回的也是undefined呻顽。

輸出undefined

預(yù)解析(重要)

js解析器執(zhí)行代碼過程:

1.預(yù)解析js代碼

預(yù)解析的過程就是在代碼中查找var與function兩個關(guān)鍵字雹顺,找到關(guān)鍵字后將,變量定義與函數(shù)賦值的過程提升到整一個代碼的最前端芬位。所以此時變量的值為undefined因為預(yù)解析只是將變量定義放到了代碼的最前端无拗,而沒有賦值的變量值為undefined带到。函數(shù)為初始值的代碼段昧碉。

2.執(zhí)行代碼

開始按順序一行一行解讀代碼

預(yù)解析題目:
題目:

console.log(a)
var a = 10;
test()
function test(){
    console.log("this is test function")
}

題目解析:

var a
function test(){
    console.log("this is test function")
}
console.log(a) // 前面有定義過變量a,沒有賦值揽惹,所以變量的值為undefined
a = 10; // 將a的值改變?yōu)?0
test() // 前面有定義過函數(shù)被饿,內(nèi)存中能找到,所以調(diào)用成功

一些題目:

// 第1題
console.log(num)
var num = 100
//輸出undefined

// 第2題
fn();
function fn() {
    console.log(123);
}
//輸出123 因為預(yù)解析

// 第3題
console.log(fn)
fn()
var fn = function () {
    console.log(123);
}
//第一個輸出undefined
//第二個報錯 fn is not a function
//相當(dāng)于 預(yù)解析先定義了一個變量fn 但fn為undefined但不是一個函數(shù) 不可以用來調(diào)用

// 第4題
fun()
var fn = function () {
    console.log('我是 fn 函數(shù)')
}
function fun() {
    console.log('我是 fun 函數(shù)')
}
fn()
fn = 100
fn()
//


// 第5題
fn()
function fn() {
    console.log('我是一個 fn 函數(shù)')
}
fn()
var fn = 100
fn()
//我是一個fn函數(shù)
//我是一個fn函數(shù)
//報錯
//

/*function fn() {
    console.log('我是一個 fn 函數(shù)')
}
var fn
函數(shù)和變量的定義詞同名 保留函數(shù) 忽視變量聲明聲明
fn()
執(zhí)行函數(shù)
*/

// 第6題
var fun = 200
fun()
var fun = function () {
console.log('我是一個 fun 函數(shù)')
}
fun()
// 第7題
var a = b
a = 0
b = 0
console.log(a)
console.log(b)
//沒有定義變量b所以報錯 報錯后 后面的代碼不執(zhí)行


// 第8題
console.log(num)
if (false) {
    var num = 100
}
//輸出undefined

預(yù)解析的總結(jié):

1.如果變量名和函數(shù)名重名了搪搏,則保留函數(shù)預(yù)解析狭握,而忽視變量預(yù)解析。
2.不執(zhí)行的代碼中如果有變量或者函數(shù)的定義疯溺,這些函數(shù)與變量也會被預(yù)解析论颅。因為預(yù)解析在執(zhí)行之前哎垦。
3.如果js的代碼報錯,則之后的代碼不再執(zhí)行恃疯。
4.賦值式函數(shù)在預(yù)解析時算作定義變量漏设,而不算定義函數(shù)。
5.函數(shù)會在函數(shù)內(nèi)部進行預(yù)解析

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

示意圖

作用域

作用域的定義:能起到作用的區(qū)域今妄,因為定義在不同區(qū)域的變量郑口,其作用域是不同的。

作用域的分類

全局作用域:

不在任何一個函數(shù)中定義的變量叫做全局變量盾鳞,全局變量的作用域是整一個script區(qū)域犬性。

<script>
    var a = 6; //全局變量a,作用域范圍也包括了下一個script
    console.log(a);
    function fn(){
        console.log(a);
    }
    fn()
</script>
局部作用域:

在函數(shù)內(nèi)部定義的變量腾仅,他的作用域的范圍就是這個函數(shù)乒裆,在函數(shù)外不能使用這個變量。

<script>
    function fn(){
        var a = 6;
        console.log(a);
    }
    fn() //輸出6
    console.log(a);//報錯a is not defined
</script>

如果全局和局部有相同的變量名攒砖,局部輸出時先考慮當(dāng)前的作用域缸兔。

<script>
    var a = 12;
    function fn(){
        var a = 6;
        console.log(a);
    }
    fn() //輸出6
    console.log(a);//輸出12
</script>

作用域鏈

函數(shù)是寫在全局當(dāng)中的,所以局部作用域是嵌套在全局作用域之中的吹艇,如果再在函數(shù)中嵌套另一個函數(shù)惰蜜,則在局部作用域中又會再嵌套一個局部作用域。這樣就形成了作用域的嵌套受神,由作用域的嵌套引發(fā)的鏈?zhǔn)浇Y(jié)構(gòu)就叫做---作用域鏈抛猖。

   var a = 10;

    function fn() {
        var b = 20;
        fun()
        function fun() {
            var c = 30;
            console.log(b);//輸出20
        }
        console.log(a);//輸出10
    }
    fn()
作用域鏈

作用域鏈的規(guī)則

  1. 當(dāng)使用一個變量時,包括:用變量作為值進行賦值鼻听、用變量進行計算箭昵、輸出變量,會先在當(dāng)前作用域中尋找變量是否有定義過變量境蜕,若定義過叹话,正常使用;若沒有在這個定義域中定義醉拓,則按照作用域鏈伟姐,返回這個定義域的上一級尋找,同理若找到正常使用亿卤,若沒有找到則重復(fù)這個操作直到全局作用域中愤兵。若在全局定義域中有,則還是可以正常使用排吴,若沒有則在使用中報錯:變量名 is not defined.
  2. 當(dāng)給一個變量進行賦值時秆乳,現(xiàn)在當(dāng)前作用域中查找是否定義過這一個變量,如果定義過則給這個變量賦值。若沒有屹堰,則和使用變量的原理一樣肛冶,直到全局作用域。不同的是若是全局作用域也沒有定義過這個變量扯键,則規(guī)則是在全局定義這個變量淑趾,并對他賦值,值為你書寫的值忧陪。
    一些練習(xí):
// function fn() {
//     console.log(num) // undefined扣泊,原因為在函數(shù)中也會進行預(yù)解析
//     return
//     var num = 100
// }
// fn()
// console.log(num); // 報錯

// var num = 10;
// fn1();
// function fn1() {
//     console.log(num);
//     var num = 20;
// }
/*
預(yù)解析:
var num
function fn1() {
  var num
  console.log(num); // undefined
  num = 20;
}
num = 10;
fn1();

函數(shù)中也會預(yù)解析

*/

// var a = 18;
// fn2();
// function fn2() {
//     var b = 9;
//     console.log(a); // 18
//     console.log(b); // 9
// }

// fn3();
// console.log(c);
// console.log(b);
// console.log(a);
// function fn3() {
//     var a = b = c = 9; // b=9
//     console.log(a); // 9
//     console.log(b); // 9
//     console.log(c); // 9
// }

// var a = b = c = 9
/*
相當(dāng)于:
var a = 9
b = 9
c = 9
*/
// console.log(a,b,c);



// function fn(a) {
//   // var a = 10
//   // -------------------
//   function a() {
//       console.log('我是函數(shù) a')
//   }
//   console.log('我是 fn 函數(shù)')
//   a()
// }
// fn(10)
習(xí)題總結(jié):
  1. 全局中有預(yù)解析,局部中也有預(yù)解析嘶摊,局部的預(yù)解析只在局部中進行對全局沒有影響延蟹。
  2. 在使用 var a = b = c =9這種方式給變量賦值時,只有第一個變量是有定義的過程也就說只有第一個變量定義等同于 var a=9其余都是直接給變量賦值叶堆。
  3. 函數(shù)定義好以后阱飘,函數(shù)名就跟變量名一樣,可以使用函數(shù)名修改這個空間中的值虱颗。
  4. 局部的預(yù)解析會在形參賦值之后沥匈,預(yù)解析中的函數(shù)會覆蓋掉形參賦的值。

遞歸函數(shù)

遞歸函數(shù)就是在函數(shù)內(nèi)部調(diào)用自己忘渔,形成循環(huán)高帖。
使用遞歸函數(shù)時,應(yīng)該注意要有一個停止函數(shù)的條件畦粮,否則會形成死循環(huán)散址。

寫遞歸函數(shù)的步驟:

  1. 先書寫一個空函數(shù),并調(diào)用
  2. 調(diào)用時傳入實參宣赔,定義形參
  3. 書寫大致的代碼
  4. 根據(jù)想要實現(xiàn)的效果給遞歸函數(shù)一個停止的條件

用遞歸函數(shù)實現(xiàn)效果:

// 求10的階和预麸,即:10+9+8+...+1
function facSum(num){
    if(num == 1){
        return 1;
    }
    return num + facSum(num-1);
}
var res = facSum(10);
console.log(res); // 55
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市儒将,隨后出現(xiàn)的幾起案子吏祸,更是在濱河造成了極大的恐慌,老刑警劉巖钩蚊,帶你破解...
    沈念sama閱讀 219,110評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贡翘,死亡現(xiàn)場離奇詭異,居然都是意外死亡两疚,警方通過查閱死者的電腦和手機床估,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評論 3 395
  • 文/潘曉璐 我一進店門含滴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來诱渤,“玉大人,你說我怎么就攤上這事谈况∩酌溃” “怎么了递胧?”我有些...
    開封第一講書人閱讀 165,474評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長赡茸。 經(jīng)常有香客問我缎脾,道長,這世上最難降的妖魔是什么占卧? 我笑而不...
    開封第一講書人閱讀 58,881評論 1 295
  • 正文 為了忘掉前任遗菠,我火速辦了婚禮,結(jié)果婚禮上华蜒,老公的妹妹穿的比我還像新娘辙纬。我一直安慰自己,他們只是感情好叭喜,可當(dāng)我...
    茶點故事閱讀 67,902評論 6 392
  • 文/花漫 我一把揭開白布贺拣。 她就那樣靜靜地躺著,像睡著了一般捂蕴。 火紅的嫁衣襯著肌膚如雪譬涡。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,698評論 1 305
  • 那天啥辨,我揣著相機與錄音涡匀,去河邊找鬼。 笑死溉知,一個胖子當(dāng)著我的面吹牛渊跋,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播着倾,決...
    沈念sama閱讀 40,418評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼拾酝,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了卡者?” 一聲冷哼從身側(cè)響起蒿囤,我...
    開封第一講書人閱讀 39,332評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎崇决,沒想到半個月后材诽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,796評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡恒傻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,968評論 3 337
  • 正文 我和宋清朗相戀三年脸侥,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片盈厘。...
    茶點故事閱讀 40,110評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡睁枕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情外遇,我是刑警寧澤注簿,帶...
    沈念sama閱讀 35,792評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站跳仿,受9級特大地震影響诡渴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜菲语,卻給世界環(huán)境...
    茶點故事閱讀 41,455評論 3 331
  • 文/蒙蒙 一妄辩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧山上,春花似錦恩袱、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至鸯屿,卻和暖如春澈吨,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背寄摆。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評論 1 272
  • 我被黑心中介騙來泰國打工谅辣, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人婶恼。 一個月前我還...
    沈念sama閱讀 48,348評論 3 373
  • 正文 我出身青樓桑阶,卻偏偏與公主長得像,于是被迫代替她去往敵國和親勾邦。 傳聞我的和親對象是個殘疾皇子蚣录,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,047評論 2 355

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

  • 每天一句:想說會有多少人問自己一下幾個問題“你這輩子到底要什么萎河,要做怎么樣的人?你現(xiàn)在能夠做什么蕉饼?你正在做什么虐杯?你...
    EndEvent閱讀 282評論 0 0
  • 概念 函數(shù)(function),也叫作功能昧港、方法擎椰,函數(shù)可以將一段代碼一起封裝起來,被封裝起來的函數(shù)具備某一項特殊的...
    白棠閱讀 176評論 0 0
  • 每天一句:想說會有多少人問自己一下幾個問題“你這輩子到底要什么值朋,要做怎么樣的人?你現(xiàn)在能夠做什么休弃?你正在做什么?你...
    王梓懿_1fbc閱讀 156評論 0 0
  • 一圈膏、函數(shù)的概念 函數(shù)是一段可以反復(fù)調(diào)用的代碼塊塔猾。 作用:在程序設(shè)計中,常將一些常用的功能模塊編寫成函數(shù)稽坤,以減少重復(fù)...
    MJ的小世界閱讀 149評論 0 1
  • 1. JS函數(shù)的概念 2. 函數(shù)的作用 3. 使用函數(shù)的好處 4.函數(shù)的分類 函數(shù)可以分為: 系統(tǒng)函數(shù) 內(nèi)置...
    阿里P9王者閱讀 352評論 0 0