JavaScript學習筆記——函式、立即執行函式、作用域、預編譯—day two
目錄
函式
原則:高內聚弱耦合(重複)
定義
函式宣告(用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;
三、將實參值和形參統一(傳參)
四、在函式體裡面找到函式宣告{函式宣告整體提升(相當於放到程式最前面)}
五、值賦予函式體,執行(宣告函式和變數的部分直接不看了)
瞭解編譯步驟後,當函式名,變數名等同名的時候,也可以不混淆。