JavaScript 函數總體概述(函數聲明/參數傳遞/返回值/加載/變量和作用域/變量聲明提升/匿名函數/回調函數)



1. 函數的概念和定義
函數就是可以重複執行的代碼塊。

① 函數聲明(自定義聲明)
使用在定義之前或之後均可
function 函數名(形參) { }

② 函數表達式(匿名函數法)
注意:使用必須在定義之後
var 變量 = function(形參) { }


③ Function對象(構造函數法)
注意:使用必須在定義之後
var 變量 = new Function(程序);



2. 函數的參數
定義:參與運算的變量
作用:爲了擴展函數的功能性,和與程序員的交互性,和代碼的複用性
實參:實際參與運算的變量
形參:形式上參與運算的變量,爲實參佔位置

JavaScript中的函數相對於其它語言的函數比較靈(特)活(殊)。
在其它語言中實參個數必須和形參個數一致,但是JavaScript中沒有函數簽名的概念,實參個數和形參個數可以不相等。JavaScript中沒有方法的重載。
① 實參個數 > 形參個數:函數正常執行,多餘的參數不參與運算
② 實參個數 = 形參個數:函數正常執行
③ 實參個數 < 形參個數:未給定值的參數默認爲undefined,是報錯還是NaN還是無法執行,取決於函數內部的邏輯
function fn(a,b) {
    alert(a+b);
    //實參個數和形參個數
    console.log(fn.length);//打印:形參個數
    console.log(arguments); //打印:實參個數,arguments是一個對象(僞數組),裝載着所有的實參,必須在函數內部使用
}




3. 函數的返回值
有return函數就有值,沒有return函數就沒有值。
函數內部的變量如果外部想要使用,必須用return關鍵字返回,那麼外部的變量才能接收。
總結:函數內部,return後面的值就是返回值
作用:函數執行後剩下結果就是返回值
alert("你好");//有參數,沒有返回值
confirm("你好");//有參數,有返回值,點擊確定返回true,點擊取消返回false
prompt();//有參數,有返回值,點擊確定返回輸入內容,沒寫內容默認爲空字符串,點擊取消返回null

總結函數功能
- 有時候我們用的是函數的邏輯
- 有時候我們用的是函數的返回值
- 而函數的參數是爲了提高函數的功能性存在的
函數的注意事項
 如果函數沒有顯式使用return語句,那麼函數有默認的返回值:undefined
② 如果函數使用return語句,那麼跟在return後面的值,就成了函數的返回值
③ 如果函數使用return語句,但是return後面不跟任何值,那麼函數的返回值也是undefined
④ 函數使用return語句後,這個函數會在執行完return語句之後停止並立即退出,return可以切斷函數,它後面的代碼不會再執行,但代碼也會被加載。
 打印函數名,等於打印整個函數;打印執行函數,等於打印返回值。
函數名+(),就是執行函數



4. 函數名、函數體和函數加載問題
① 函數名是什麼?
函數名 == 整個函數
② 函數加載問題
JS加載的時候,只加載函數名,不加載函數體。所以如果想使用內部的成員變量,需要調用函數。



5. 變量和作用域(函數中的變量需要函數執行之後才能使用)
(1)全局變量和局部變量
- 任何位置沒有var的都是全局變量(成員變量),或者函數之外用var定義的也是全局變量
- 函數內部有var的是局部變量,形參也是局部變量
(2)隱式全局變量
- 函數內部沒有var的是全局變量
function  fn(){
    var  a  =  b  =  c  =  1;   // b和c就是隱式全局變量(等號)
    var  a = 1;  b = 2;  c = 3;     // b和c就是隱式全局變量(分號)
    var  a = 1 ,  b = 2 ,  c = 3;    // b和c不是隱式全局變量(逗號)
}

(3)其它
- 函數內部可以訪問到該函數所屬的外部作用域的變量(作用域鏈)
- 不使用var聲明的變量是全局變量,不推薦使用。
- 變量退出作用域之後會銷燬,全局變量關閉網頁或瀏覽器纔會銷燬



6. 變量聲明提升(出現原因:預解析)
就是在頁面加載完畢之後,js執行之前,需要先預覽一遍整體的js代碼,把所有非function內部的變量提升到頁面的最頂端。如果在定義變量之前使用了變量,就會出現變量聲明提升。
- 使用變量的時候變量的值爲undefined,計算後形成NaN
- 變量聲明提升在全局和局部都是會出現的
- 對於變量,只提升變量名,不提升變量值
- 對於函數,是整體提升的
(詳細解析見後續文章)



7. 匿名函數
定義:沒有命名的函數
作用:
    ①不需要定義函數名的時候(一般用在綁定事件的時候)  
    ②書寫起來更簡便

調用方法:
    ① 直接調用
var fn = function() {}
fn();

    ② 自調用
(function(){alert(1)})();

    ③ 事件綁定
    ④ 定時器




8. 函數是一種數據類型
function



9. 回調函數
- 簡單理解:就是函數做爲參數
- 複雜理解:回調函數就是一個通過函數調用的函數。如果你把函數的指針(地址)作爲參數傳遞給另一個函數,當這個指針被用來調用其所指向的函數時,我們就說這是回調函數。
fn(1,2,demo1);//使用函數名就相當於傳遞了整個函數

function fn(num1,num2,fun){
    var sum = fun(num1,num2);
    alert(sum);
}

function demo1(n,m){
    return n+m;
}




10. 遞歸
定義:函數自己調用自己
使用:必須有跳出條件
(詳細解析見後續文章)



11. 閉包
定義:函數作爲返回值
fn()();//第一個小括號是對fn的調用,調用後會返回一個值,後面的括號是對返回值的調用
function fn(){
    return function demo(){
        alert(50);
    }
}
(詳細解析見後續文章)



12. parseInt 和 toString 問題
parseInt把任何進制轉換成10進制
十進制值 = parseInt(數值,進制);

toString把10進制轉換成任何進制
任何進制值 = 十進制值.toString(進制);



13. 參數傳遞問題
func(num); //調用函數
所謂的調用函數傳參就是將參數中的數據給函數中的參數變量賦值。
調用函數的時候:
-> 將參數拷貝一份
-> 跳轉到函數體
-> 進入函數體之前將完成一次賦值,num = 被拷貝的值
不嚴謹的描述,參數傳遞就是參數賦值
-> 如果傳遞的是值類型:值類型會被拷貝,拷貝的是數據,因此在函數內的變量,與函數外的變量是值相同的兩個不同變量,值類型在函數內修改的變量以後,函數結束後,數據無影響。
-> 如果傳遞的是引用類型:引用會被拷貝,拷貝的是地址,而數據還是隻有一個,也就是說,函數內與函數外是兩個不同的變量,但是指向同一個對象,無論使用函數內,還是函數外的變量對該對象做操作,都是一樣的,因此在函數內修改對象的成員,函數結束後,修改結果會保持下來。




小知識
① 函數不調用不執行
② 函數名就等於(整個函數)
③ 加載函數的時候,只加載函數名,不加載函數體
④ 參數相當於局部變量
⑤ 就近原則使用變量
⑥ 兩個平級的函數中的變量不會相互影響(可以使用同樣的形參名)




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章