javascript中沒有main函數。main函數常用於Java與C語言中,又稱主函數,是要求有返回值的,返回0代表程式正常執行成功,返回非0值代表程式異常結束;而在JavaScript中不存在該函數。
本教學操作環境:windows10系統、javascript1.8.5版、Dell G3電腦。
javascript沒有main函數
簡介
main函數,又稱主函數,作為絕大部分C程式唯一的入口,是要求有返回值的,該返回值返回給(如作業系統)來表明該程式的執行狀況。返回0代表程式正常執行成功,返回非0值代表程式異常結束,因此返回值需要是int整型,於是有了int main()的規範。
如果使用void main(),即宣告主函數沒有返回值,程式雖能編譯、執行成功,卻不利於程式的啟用者判斷其狀態,這對於有很多C程式構成的大型專案來說是可能是致命的。
尤其從C99標準(1999年制定的官方C語言標準第二版)開始必須使用int main(),如果沒有加return 0;語言,C99要求編譯器自動新增(自己寫上是個好習慣)。只宣告main()的話,系統預設為int main()。void main()無論何時都不應該使用,因為主函數必須有返回值表明程式的執行狀態(在程式碼中不使用void main()是一個良好的習慣)。
定義
在最新的C99標準中,只有以下兩種定義方式是正確的:
int main(void) int main(int argc, char *argv[]) // char *argv[]可以寫成char **argv
引數
void:不接受任何引數;
argc:代表程式所執行環境傳遞給程式的引數數量;
argv:指向argc+1個指標的陣列的首元素的指標。陣列末元素為空指標,而若前面有元素,則它們指向表示從宿主環境傳遞給程式的引數的字串。若argv[0]不是空指標(或argc>0),則它指向表示程式名的字串。若程式名從宿主環境不可用則該字串為空。
返回值
返回值會用作隱式呼叫exit()的引數,值0和EXIT_SUCCESS指示成功終止,值非0和EXIT_FAILURE指示不成功終止。
範例如下:在JavaScript中虛構一個main函數
在C和Java中,都有一個程式的入口函數或方法,即main函數或main方法。而在JavaScript中,程式是從JS原始檔的頭部開始執行的。但是某種意義上,我們仍然可以虛構出一個main函數來作為程式的起點,這樣一來不僅可以跟其他語言統一了,而且說不定你會對JS有更深的理解。
1. 實際的入口
當把一個JavaScript檔案交給JS引擎執行時,JS引擎就是從上到下逐條執行每條語句的,直到執行完所有程式碼。
2. 作用域鏈、全域性作用域和全域性物件
我們知道,JS中的每個函數在執行時都會產生一個新的作用域。具體來說,在執行流程進入函數時會建立一個新的作用域,在函數執行完成退出時會銷燬這個作用域。函數的形參、區域性變數都會繫結到這個作用域裡,當函數呼叫完成作用域銷燬時,它們隨之被銷燬。當然在特殊情況下,如果函數返回時作用域中的某些變數仍然被參照,那麼作用域以及這些被參照的變數就不會被銷燬,從而形成所謂的閉包。
另一方面,我們知道函數是可以巢狀的,因而作用域也是可以巢狀的。函數在定義的時候,JS引擎會給每個函數設定一個稱為[[scope]]內建屬性,它指向外部函數的詞法作用域。通過這種方式,多個作用域形成了鏈式結構,稱為作用域鏈。通常情況下,在任意時刻只存在一條作用域鏈,即從正在執行的函數的作用域開始,層層上溯,直到最外層的全域性作用域。
[注]:作用域鏈上的函數就是JS原始碼裡的層層巢狀的函數,跟函數執行時的順序或函數呼叫棧無關,這也是詞法作用域這個稱呼的由來。
全域性作用域是一個特殊的作用域,它不是一個函數作用域,但它是所有函數作用域的外層作用域,也是所有作用域鏈的終點。因此只要程式沒有退出,全域性作用域總是存在的,全域性作用域內的變數也是一直有效的。
[函數3的作用域]-->[函數2的作用域]-->[函數3的作用域]-->[全域性作用域]
另外,對應於全域性作用域,還有一個全域性物件。在瀏覽器中,全域性物件就是window物件。全域性物件是個特殊的物件:
在全域性作用域中定義的變數,都會繫結到全域性物件。
在任意作用域中定義的變數,如果定義時沒有用 var 關鍵字,都會繫結到全域性物件。
在全域性作用域中, this 指向全域性物件。
從上面列舉的這些特性可以看出,如果把全域性作用域當成一個物件的話,那麼實際上它就是全域性物件。另外,這也解釋了在全域性作用域中,下面的四條語句為什麼是等價的:
var a = 1; a = 1; window.a = 1; this.a = 1;
3. 虛構的main函數
既然都是作用域,為什麼要有一個特殊的全域性作用域呢?我們總是喜歡簡單化、一致性,而儘量避免複雜化、特殊性。所以很自然地,我們會想能否讓全域性作用域看起來跟函數作用域沒什麼區別?答案是肯定的。我們可以做這樣的構想:
我們想象,在JS引擎執行原始檔時,會將檔案中的程式碼包裝到一個叫做main的函數中。然後把這個main函數作為程式的入口。
也就是說,假設一個JS檔案中有這樣的程式碼:
var a = 1; var b = 2; function add(x, y) { var z = x + y; return z; } console.log(add(a, b));
JS引擎在程式開始執行前會把它包裝成一個main函數:
// 虛構的main函數 function main() { var a = 1; var b = 2; function add(x, y) { var z = x + y; return z; } console.log(add(a, b)); }
然後,呼叫這個main函數:
main._current_scope_ = window; // 將全域性作用域(物件)設為window main.call(window) // 將this指向window
4. 意義何在?
(1) JS也有了入口函數main,跟其他語言一致了。
(2) 省去了全域性作用域的概念,或者說全域性作用域也成了函數作用域。
(3) 通過上面對main函數的呼叫過程,可以明白全域性作用域中的那些特殊性質的由來。
(4) 最後一點,將所有JS原始碼當成一個函數,是為了後面講事件佇列、事件迴圈做鋪墊。
相關推薦:
以上就是javascript有main函數嗎的詳細內容,更多請關注TW511.COM其它相關文章!