1. 程式人生 > >JavaScript學習筆記——函式、立即執行函式、作用域、預編譯—day two

JavaScript學習筆記——函式、立即執行函式、作用域、預編譯—day two

目錄

函式

定義

組成形式

遞迴

立即執行函式

作用域

變數作用域

函式作用域[[scope]]

作用域鏈

預編譯

JS執行分三步:

預編譯執行分五步:


函式

原則:高內聚弱耦合(重複)

定義

        函式宣告(用function宣告函式)

        函式表示式

三種定義方式:

        function test(){
            document.write('abc');
        }
        test();//定義完函式,呼叫才能執行。
        // 命名函式表示式,忽略名字,沒什麼用。
        var test = function abc() {
            document.write('123');
        }
        test();
        // 匿名函式表示式,最常用。
        var test = function() {
            document.write('123');
        }
        test();
    

組成形式

        函式名稱

             多個單詞拼接單詞,小駝峰規則,第一個單詞小寫,後面單詞第一個字母大寫。

        引數

              形參(函式定義時的引數)

              實參(呼叫的時候實際傳的引數)

              不用宣告引數資料型別,實參形引數量不對應也不會報錯,有幾個用幾個。不定參(不給定形引數量)用的最多。

        返回值

              return ;終止函式(後面的語句不執行),返回值。

遞迴

特別複雜的程式別用遞迴,程式執行很慢,比for迴圈唯一的好處只是程式碼簡潔一點。

1.找規律

2.找出口

       //n的階乘
       function mul(n) {
            if (n == 1) {
                return 1;
            }//遞迴的出口,一個遞迴到最後的已知子單元。
            return n * mul(n - 1);
        }
        mul(3);

立即執行函式

很多函式只會用一次,之後一直在等待執行浪費記憶體空間,而立即執行函式執行完就會把函式立即刪除,之後呼叫也找不到。

主要用於初始化功能的函式。

基本形式:(function (){}())

其它方面與普通函式無任何區別,有執行期上下文,要預編譯等等。

var mum=(function (a,b,c){
            var d=a+b+c;
            console.log(d);
        }(1,2,3));

結果為6。

作用域

變數和函式生效的區域

變數作用域

全域性變數:函式外面的變數是全域性變數,函式裡函式外都能訪問

區域性變數:函式裡面的變數是區域性變數,函式外無法呼叫,相對而言的,函式裡面的函式可以訪問外層函式的區域性變數。

作用域的訪問順序:簡而言之就是,裡面的可以訪問外面的,外面的不能訪問裡面的,平級的區域性變數不能相互訪問。

全域性函式,區域性函式同理,寫在函式裡面還是函式外面的函式。

全域性物件和全域性變數的關係

1.任何變數未經宣告就賦值,則此變數為全域性物件(window)所有。a = 10;

2.一切宣告的全域性變數,全是window的屬性,window就是全域性的域。

var a = 123;

window.a=123; 

函式作用域[[scope]]

每個javascript函式都是一個物件,物件中有的屬性可以訪問,有的不能,這些屬性僅供javascript引擎存取,如[[scope]]。

[[scope]]就是函式的作用域,其中儲存了執行期上下文的集合。

執行期上下文:當函式執行時,會建立一個稱為執行期上下文的內部物件(AO)。一個執行期上下文定義了一個函式執行時的環境,函式每次執行時對應的執行期上下文都是獨一無二的,所以多次呼叫一個函式會導致建立多個執行期上下文,當函式執行完畢,它所產生的執行上下文被銷燬。

作用域鏈

[[scope]]中所儲存的執行期上下文物件的集合,這個集合呈鏈式連結,我們稱這種鏈式連結為作用域鏈。查詢變數時,要從作用域鏈的頂部開始查詢。Activation Object(AO)到Global Object(GO)。

原理圖解:

例子:

由上到下時間執行過程:

預編譯

JS執行分三步

語法分析(通篇掃描是否有語法錯誤),預編譯(發生在函式執行的前一刻),解釋執行(一行行執行)。

預編譯執行分五步:

一、建立AO物件(Activation Object  執行期上下文)

二、找形參和變數宣告,將變數和形參名作為AO屬性名,值為undefined.

    變數宣告提升(變數放到後面也不會報錯,只是未定義型別)如:console.log(a);var a=10;結果undenfined;

三、將實參值和形參統一(傳參)

四、在函式體裡面找到函式宣告{函式宣告整體提升(相當於放到程式最前面)}

五、值賦予函式體,執行(宣告函式和變數的部分直接不看了)

瞭解編譯步驟後,當函式名,變數名等同名的時候,也可以不混淆。