04.函數(shù)

一.初步了解函數(shù)

1.函數(shù)的定義和調(diào)用

1.1 函數(shù)定義

函數(shù)其實就是將多條語句組合成一個“語句軍團(tuán)”,集體作戰(zhàn)

//定義一個函數(shù),函數(shù)就是一組語句的集合
function fun(){
    console.log(1);
    console.log(2);
    console.log(3);
    console.log(4);
}

//函數(shù)調(diào)用
fun(); 

\color{red}{函數(shù)必須先定義然后才能調(diào)用}
定義一個函數(shù),用關(guān)鍵字function來定義
function后面有一個空格,后面就是函數(shù)名字,函數(shù)的 名字也是標(biāo)識符,既然是標(biāo)識符,那么命名規(guī)范和變量命名就是一樣的。

定義一個函數(shù)也叫聲明一個函數(shù)

function 函數(shù)名(){

}

函數(shù)如果不調(diào)用,那么里面的語句就不會執(zhí)行,不調(diào)用就等于白寫。

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

調(diào)用一i個函數(shù)的方法非常簡單,函數(shù)名后面加一個(),
( ) 是運算符, 表示執(zhí)行一個函數(shù)

執(zhí)行函數(shù):

函數(shù)名()

一旦調(diào)用了函數(shù),函數(shù)內(nèi)部的語句就會執(zhí)行

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

2.1 參數(shù)的了解

可以通過參數(shù)讓函數(shù)內(nèi)部的語句有所不同
定義函數(shù)的時候,內(nèi)部語句可能有一些懸而未決的量,就是變量,這些變量,我們要求在定義的時候羅列在小括號中:
比如:

function fun(num){
      console.log("這已經(jīng)是我第” +  num + "此說我愛你!");
}

調(diào)用的時候,要把這個變量的真實的值,一起寫在括號里,這樣隨著函數(shù)的調(diào)用,這個值也傳給了num';這就是參數(shù)傳遞
執(zhí)行這個函數(shù):

fun(99);

羅列在function小括號中的參數(shù),叫做\color{red}{形式參數(shù)};
調(diào)用時傳遞的值,叫做\color{red}{實際參數(shù)}
形式參數(shù)就像占位置,先把位置站好,等你來賦值

2.2 參數(shù)個數(shù)

參數(shù)可以有無數(shù)個,用逗號隔開。

//有多少形式參數(shù)都可以,都羅列出來
function fun( a, b ){
    console.log( a + b);
}
fun( 2,6);   //輸出8
fun( 6,18);  //輸出24

定義函數(shù)的時候,不需要指定類型:

function sum( a,b){
  console.log( a + b);

也就是說調(diào)用的時候,傳進(jìn)去的值是什么類型,就是形參a、b就是什么類型

sum( "5" , 20);

輸出520 ,做的時連字符的運算

2.3 實參和形參個數(shù)不等

聲明函數(shù)的時候和調(diào)用函數(shù)的時候參數(shù)個數(shù)可以不一樣,也不報錯。

  • 實參個數(shù)小于形參個數(shù)
sum( 20 );    //  NaN

以為只傳了一個參數(shù),b就沒有傳遞,b被隱式的var了,所以值時undefined。
10+undefined就是NaN
也就是說沒有實參傳遞二點形參就是undefined。

  • 實參個數(shù)大于形參個數(shù)
sum( 10,20,30,40,50);    //30

只有前兩個參數(shù)被形參接受了,后面的參數(shù)無視了,
形參會按順序接收實參,

2.4 arguments

每一個函數(shù)里面都有一個隱式的arguments,這個時系統(tǒng)已經(jīng)給你創(chuàng)建好的,每個函數(shù)內(nèi)部都有,arguments是類似于數(shù)組的類數(shù)組,就是實參列表
類數(shù)組本質(zhì)上是一個對象,涵蓋了所有的實參

調(diào)用函數(shù)的時候,比如:

fun(45,56,346,335,231);

此時函數(shù)內(nèi)部,arguments就有一個下標(biāo),就依此等于上面調(diào)用的數(shù):

arguments[0]     //45
arguments[1]     //56
arguments[2]     //346
arguments[3]     //335
arguments[4]     //231
.....

如果函數(shù)里面有形式參數(shù)列表,那么是和arguments同步的:

 function fun(a,b){
         arguments[0] = 8;//改變第一個參數(shù)值
         alert(a);   // 8 ,彈出改變后的值

        console.log( arguments.length); //實參的長度
        console.log( fun.length); //形參的 長度 

fun(45,56,346,335,231);

arguments的功能是模擬函數(shù)的重載,使得同一個函數(shù),根據(jù)參數(shù)個數(shù)額不同,有不同的作用

4. 返回值

函數(shù)可以通過參數(shù)來接收東西,可以通過return的語句來返回值

function sum(a,b){
      return a + b;//現(xiàn)在這個函數(shù)的返回值就是a+b的和
}
console.log( sum(5,4));//sum沒有輸出功能,就要用console.log輸出
//sum(5,4)實際上就成為了一個表達(dá)式,用來計算結(jié)果
//計算結(jié)果就是9,相當(dāng)于console.log(9);

函數(shù)只能有唯一的return,有if語句除外,因為if語句是分支語句

程序遇到了return,將立即返回結(jié)果,返回調(diào)用的地方,而函數(shù)內(nèi)return后面的語句將不再執(zhí)行

function fun(){
    console.log(1);
    console.log(2);
    return;    //返回一個空值
    console.log(3);//這行語句不執(zhí)行,因為函數(shù)已經(jīng)return了所以不會打印3
}
fun();  // 1 ,2

程序是先執(zhí)行內(nèi)層在執(zhí)行外層。
函數(shù)可以接收很多值,返回一個值

函數(shù)的意義:

  1. 在出現(xiàn)大量程序相同的時候,可以封裝為一個function,這樣只要寫一次代碼就可以調(diào)用很多次,減少代碼耦合
  2. 在調(diào)用一個函數(shù)的時候,不用關(guān)心函數(shù)內(nèi)部的實現(xiàn)細(xì)節(jié),只要可以運用,并能給我們開發(fā)帶來好處
  3. 模塊化編程,然復(fù)雜的邏輯變得簡單

4. 遞歸

函數(shù)內(nèi)部又調(diào)用了函數(shù)自身,我們把這種情況叫做遞歸

斐波那契數(shù)列就是經(jīng)典的遞歸算法:

1、1、2、3、5、8、13、21、34、55、89、144、233……
輸出斐波那契數(shù)列

//1、1、2、3、5、8、13、21、34、55、89、144、233……
//fib(n)   就能得到第n位的數(shù)字
//fib(2) = 1
//fib(5) = 5
//fib(6) = 8
//fib(10) = 55
function fib(n){
      if( n == 1 || n == 2){
            return 1;
}else{
    return fib( n - 1) + fib( n - 2);

        }
}
//一點一點計算
for( var i =1; <= 55 ; i++){
      console.log(fib(i));
}

二.函數(shù)表達(dá)式

定義函數(shù)處理使用function之外,還有一種方法,就是函數(shù)表達(dá)式。就是函數(shù)沒有名字,稱為“匿名函數(shù)”,為了能夠調(diào)用它,我們把這個匿名函數(shù),直接賦值給一個變量

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

想調(diào)用這個函數(shù)的時候,就可以直接使用sum變量來調(diào)用。

console.log( sum(3,6) );

如果現(xiàn)在這個表達(dá)式中的function不是匿名函數(shù),而是有名字的:

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

那么JS表現(xiàn)非常的奇怪,在外部只能用sum()來調(diào)用,fun()會引發(fā)錯誤!

也就是說,JS這個奇怪的特性,給我們提了個醒,定義函數(shù),只能用這兩種方法中的其一,不建議雜糅:

第一種,通過函數(shù)聲明定義函數(shù)

 function sum(){
}

第二種,通過匿名函數(shù)的賦值定義函數(shù)

var sum = function(){

}

建議不要混用,這么寫也不會錯

var xixi = function haha(){
}

三.函數(shù)聲明的提升

JS在執(zhí)行前,會有一個解析的過程,會把所有的函數(shù)聲明,都提升到了最最開頭,然后再執(zhí)行第一行語句
所以,function定義在哪里,都不重要,程序總能找到這個函數(shù)

//先調(diào)用
fun();
//然后定義
function fun(){
  console.log("我是函數(shù),我執(zhí)行了");
}

不會引發(fā)錯誤,打印能正常執(zhí)行。

3.1. 聲明函數(shù)和函數(shù)表達(dá)式提升方式不同

函數(shù)聲明會被提升,但函數(shù)表達(dá)式卻不會提升
函數(shù)表達(dá)式提升的是變量,變量提升后并不是一個函數(shù),所以在表達(dá)式之前執(zhí)行,會報錯,為類型錯誤,因為不是函數(shù)

fun() ;//報錯
var fun = function(){
      alert("我是函數(shù),我執(zhí)行了");
}

這提了個醒,沒有極特殊的理由,都要使用function 關(guān)鍵字來定義函數(shù),而不要使用函數(shù)表達(dá)式來定義函數(shù).

3.1.1 函數(shù)優(yōu)先
sum();//現(xiàn)在這個sum到底是函數(shù)還是變量8呢
//函數(shù)優(yōu)先,遇到同名標(biāo)識符,預(yù)解析階段一定把這個標(biāo)識符給函數(shù)
var sum = 8;//定義一個變量,是8
  function sum(){
    alert("我是sum函數(shù),我執(zhí)行了");
}

面試很容易靠,就常見的面試題:

foo();
var foo;
function foo(){
    console.log(1);
}
foo = function(){
  console.log(2)
}

函數(shù)優(yōu)先,
現(xiàn)在foo這個標(biāo)識符沖突了,一個函數(shù)叫做foo,一個變量也叫做foo,預(yù)解析階段,如果遇見標(biāo)識符沖突,這個標(biāo)識符給函數(shù)

四.IIFE

IIFE就是immediately-invoked function expression,即時調(diào)用函數(shù)表達(dá)式

如果一個函數(shù),在定義的時候我們就直接想調(diào)用它,就是一個IIFE
視圖在定義函數(shù)的后面,直接寫圓括號:

function fun(){
    alert("hello ");
}();

控制臺報錯,這是因為函數(shù)是一個函數(shù)體,并不是表達(dá)式,只有表達(dá)式能夠用()來執(zhí)行。
所以就要把function fun(){}“降級”,從函數(shù)體降級為表達(dá)式。

+function fun(){
    alert("hello");
 }();
-function fun(){
    alert("hello");
 }();

更通常更常用的:

(function fun(){
      alert("hello");
})(); 

用這種方法定義的函數(shù),名字是無效的,其他的地方是調(diào)用這個函數(shù):

fun();

所以IIFE里面的函數(shù),都是匿名函數(shù):

(function(){
  alert("哈哈");
})();

上面就是一個標(biāo)準(zhǔn)的IIFE.

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

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

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