JS 函數 聲明函數 函數三要素 箭頭函數 回調函數


函數

  可以實現一定功能的一段代碼的封裝。

注:函數創建過后,在內存堆中以一段字符串文本儲存,不執行時不會產生任何作用,就單單是存了一段字符串。

創建函數

  1、字面量(聲明式,推薦)
 
      關鍵字  標識符  小括號  {函數體}
 
    例:
function F65(){
    console.log(`我是一個函數F65`);
 }

   

  2、表達式(匿名函數表達式)
 
      關鍵字  標識符 = function ()  {函數體}
    例:
let F66 = function () {
    console.log(`我是一個函數F66`);
}
let F66 = function F67() {
    console.log(`我是一個函數F66`);
}
F66();//我是一個函數F66
console.log(F66.name);//F67
console.log(F66);//[Function: F67]
//F67();//報錯  F67 is not defined
//這個情況有點奇葩
 function F67() {
            console.log(`我是一個函數F67`);
        }
  F67();//我是一個函數F67
//意味着,前面並沒有聲明變量 F67,前面的F67只單單作為函數的一個name,但是調用時卻必須使用F66作為函數名,有點扯
 

 

  3、構造函數
 
        關鍵字  標識符 = new Function ();
    例:
let F68= new Function(
    "console.log(123)"
);

注:內存棧  F68:函數的引用;

  內存堆  函數:"console.log(123)",就是個字符串。

 

函數三要素

  一、函數名

    函數名取名一般要求是動詞或動賓格式,望文知意,其他的和變量標識符一樣,並且也會和變量名沖突。

  

  二、參數

      形參:創建函數時,添加的參數
      實參:調用函數時,添加的參數
注:形參會有初始值:undefined。
 
     調用函數時,實參傳給形參的過程相當於:
        let 形參 = 實參;
     有幾個參數,就對應幾個let。
 
     當形參與實參個數不同,在傳統開發語言中,個數不同會報錯,即不執行。JS不會:
  
          形參個數大於實參個數  多的形參,值為undefined
  
          實參個數大於形參個數  多的實參,不使用
 
  擴展:
      1、在最后添加一個擴展運算的變量(獲取多的實參) 數組
       必須寫在最后一個形參位置(尾形參,寫在前面會報錯),且只能有一個
  
      2、arguments獲取所有實參的內容(類數組)
  
        類數組:
          1、可以用下標取值arguments[0]
          2、可以用length獲取長度(個數)
          3、但不能數組的方法,例push()會報錯
  
  注:函數名.length取的是形參個數(不包含擴展運算符的標識符)。
function F65(a,b,c,...d){

    console.log(a,b,c);//A B C
    console.log(d);//[ 'D', 'E', 'F', 'G', 'H' ]
    console.log(F65.length);//3
    console.log(F65.arguments);//鍵值對的實參
    console.log(F65.arguments[0]);//A
}
F65("A","B","C","D","E","F","G","H");

 

function f65(x,y,z,i){
     console.log(arguments[0]);//1
     x=2;
     console.log(arguments[0]);//2
     arguments[0]=5;
     console.log(x);//5
     //形參發生值的改變,相對應的arguments也會發生改變
     //arguments發生值的改變,相對應的形參不會發生改變
     console.log(i);//un
     i=2;
     console.log(i);//2
     console.log(arguments[3]);//un
     //當形參比實參多時,對多的形參進行賦值;
     //相對應的arguments不改變(即無效,也就是打印undefined)
 }
 f65(1,2,3);

注: 函數名.arguments 和直接 arguments 是不一樣的,其實一般都是直接用 arguments。

 

  參數解構

function fn(a,b,{c,d}){
    //相當於
    let a=參數1;
    let b=參數2;
    let {c,d}=參數3;
}
//意味着參數3傳的是一個對象
//默認值 {c,d=12}={}    {}是參數默認值,d=12是解構默認值

 

 

  三、返回值:return

    
    每個函數必須有return,如果沒有添加return語句,計算機會自動在函數的最后一行補一個return,返回值為undefined。
    返回函數的結果(常量、變量、公式、表達式),同時終止函數,即不會執行return后面的代碼。

 

 參數的默認值

  函數的形參在書寫時可以直接賦值,(不賦值也會有:undefined),函數被調用時,如果形參有對應的實參,就用實參的值,沒有就用默認值。

  給形參傳值:undefined,函數也會使用該形參的默認值(不一定是undefined),

  .length獲取形參個數時,有賦值默認值的形參不會計入個數,如果賦值默認值的形參寫在第一個,長度會為0。

  因此,推薦把需要賦值默認值的形參寫到最后。

 

 ES6 箭頭函數

    

        x=> num2.has(x)    大多數時候就這個模板,函數返回表達式(num2.has(x))的結果
 

  一般有以下特點:

        1、可以省略 書寫 function

        2、如果只有一個形參,可以不打小括號

        3、如果只有一條執行語句,可以不打大括號

        4、只有一條執行語句,並且需要返回這條語句的結果,可以不用寫return

        5、不可以使用arguments

        6、不會把自己的this綁定到函數上

        7、不可以用作構造函數

  多數時候使用箭頭函數只有一條語句,就是為了簡潔方便:

let num1 = new Set([1, 2, 3, 4]);
let num2 = new Set([3, 4, 5, 6]);
// 並集
let union = new Set([...num1,...num2]);
console.log(union);//Set { 1, 2, 3, 4, 5, 6 }
//交集
let intersect = new Set(
    [...num1].filter(x=> num2.has(x)));
console.log(intersect); //Set { 3, 4 }
//差集
let difference = new Set(
    [...num1].filter(x => !num2.has(x)));
console.log(difference); //Set { 1, 2 }

 

回調函數

   把一個函數A,當參數傳遞給另一個函數B進行調用,函數A就是回調函數。

    把箭頭函數當做回調函數用的最多。

  常用的回調函數

    

//數組的排序
let arr = [1, 3, 7, 6, 9, 4, 6, 2];
let arr1 = arr.sort(
    function (a,b){
        // return b-a;
        return a-b;
    }
)
console.log(arr1);

console.log(arr.sort((a, b) => a - b)); //升序
console.log(arr.sort((a, b) => b - a)); //降序

  回調函數用的非常多,相當重要。

arr.every(
    function(index){
        return index%2==0;
    }
)//以下為簡寫
// every  數組中每個值都滿足條件才返回true
console.log(arr.every(index => index % 2 == 0)); //false
//some  數組中有一個條件滿足則返回true
console.log(arr.some(index => index % 2 == 0)); //true
//filter(過濾) 返回所有滿足條件的值
console.log(arr.filter(index => index % 2 == 0)); //[6,6,4,2]
//map  返回每個值是否滿足條件
console.log(arr.map(index => index % 2 == 0)); //[ false, false, true, true, true, false, true, false ]

 

IIFE

  Immediately Invoked Function Expression

     立即執行函數,創建即調用,調用后即銷毀

注:當立即執行函數中的變量在外面有調用時,變量會不銷毀,但是會“隱形”,只有調用它的“人”看得到。

//一般書寫方式
(function fn(){
    console.log("F65");
})()
//也可以
(function fn(){
    console.log("F65");
}())

!(function fn(){
    console.log("F65");
}())

-(function fn(){
    console.log("F65");
}())
//主要是為了讓這一段代碼與其他代碼隔開,不會有歧義,形成一個整體

 

總結

  函數的表現形式:

    1、聲明式

function fn(){}

    2、表達式

let fn = function(){}

    3、匿名函數

      不需要起名字的地方,function(){},並不能單獨書寫,在特定的地方出現,比如作為一個返回值、參數,或者立即執行函數

function fn(){
   return function(){};          
};
function fn(function(){}){};
(function(){})();

     立即執行函數、回調函數、箭頭函數,都可以算作匿名函數的一種情況。

     4、特殊函數、遞歸函數

    其實就是函數直接或者間接的調用自己。遞歸一定要給出遞歸結束條件(遞歸出口)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM