JavaScript學(xué)習(xí)筆記(三):JavaScript也有入口Main函數(shù)
在C和Java中,都有一個(gè)程序的入口函數(shù)或方法,即main函數(shù)或main方法。而在JavaScript中,程序是從JS源文件的頭部開始運(yùn)行的。但是某種意義上,我們?nèi)匀豢梢蕴摌?gòu)出一個(gè)main函數(shù)來作為程序的起點(diǎn),這樣一來不僅可以跟其他語言統(tǒng)一了,而且說不定你會(huì)對(duì)JS有更深的理解。
1. 實(shí)際的入口
當(dāng)把一個(gè)JavaScript文件交給JS引擎執(zhí)行時(shí),JS引擎就是從上到下逐條執(zhí)行每條語句的,直到執(zhí)行完所有代碼。
2. 作用域鏈、全局作用域和全局對(duì)象
我們知道,JS中的每個(gè)函數(shù)在執(zhí)行時(shí)都會(huì)產(chǎn)生一個(gè)新的作用域。具體來說,在執(zhí)行流程進(jìn)入函數(shù)時(shí)會(huì)建立一個(gè)新的作用域,在函數(shù)執(zhí)行完成退出時(shí)會(huì)銷毀這個(gè)作用域。函數(shù)的形參、局部變量都會(huì)綁定到這個(gè)作用域里,當(dāng)函數(shù)調(diào)用完成作用域銷毀時(shí),它們隨之被銷毀。當(dāng)然在特殊情況下,如果函數(shù)返回時(shí)作用域中的某些變量仍然被引用,那么作用域以及這些被引用的變量就不會(huì)被銷毀,從而形成所謂的閉包。
另一方面,我們知道函數(shù)是可以嵌套的,因而作用域也是可以嵌套的。函數(shù)在定義的時(shí)候,JS引擎會(huì)給每個(gè)函數(shù)設(shè)置一個(gè)稱為[[scope]]內(nèi)置屬性,它指向外部函數(shù)的詞法作用域。通過這種方式,多個(gè)作用域形成了鏈?zhǔn)浇Y(jié)構(gòu),稱為作用域鏈。通常情況下,在任意時(shí)刻只存在一條作用域鏈,即從正在執(zhí)行的函數(shù)的作用域開始,層層上溯,直到最外層的全局作用域。
[注]:作用域鏈上的函數(shù)就是JS源碼里的層層嵌套的函數(shù),跟函數(shù)執(zhí)行時(shí)的順序或函數(shù)調(diào)用棧無關(guān),這也是詞法作用域這個(gè)稱呼的由來。
全局作用域是一個(gè)特殊的作用域,它不是一個(gè)函數(shù)作用域,但它是所有函數(shù)作用域的外層作用域,也是所有作用域鏈的終點(diǎn)。因此只要程序沒有退出,全局作用域總是存在的,全局作用域內(nèi)的變量也是一直有效的。
[函數(shù)3的作用域]-->[函數(shù)2的作用域]-->[函數(shù)3的作用域]-->[全局作用域]
另外,對(duì)應(yīng)于全局作用域,還有一個(gè)全局對(duì)象。在瀏覽器中,全局對(duì)象就是window對(duì)象。全局對(duì)象是個(gè)特殊的對(duì)象:
在全局作用域中定義的變量,都會(huì)綁定到全局對(duì)象。
在任意作用域中定義的變量,如果定義時(shí)沒有用 var 關(guān)鍵字,都會(huì)綁定到全局對(duì)象。
在全局作用域中, this 指向全局對(duì)象。
從上面列舉的這些特性可以看出,如果把全局作用域當(dāng)成一個(gè)對(duì)象的話,那么實(shí)際上它就是全局對(duì)象。另外,這也解釋了在全局作用域中,下面的四條語句為什么是等價(jià)的:
var a = 1; a = 1; window.a = 1; this.a = 1;
3. 虛構(gòu)的main函數(shù)
既然都是作用域,為什么要有一個(gè)特殊的全局作用域呢?我們總是喜歡簡單化、一致性,而盡量避免復(fù)雜化、特殊性。所以很自然地,我們會(huì)想能否讓全局作用域看起來跟函數(shù)作用域沒什么區(qū)別?答案是肯定的。我們可以做這樣的構(gòu)想:
我們想象,在JS引擎執(zhí)行源文件時(shí),會(huì)將文件中的代碼包裝到一個(gè)叫做main的函數(shù)中。然后把這個(gè)main函數(shù)作為程序的入口。
也就是說,假設(shè)一個(gè)JS文件中有這樣的代碼:
var a = 1;
var b = 2;
function add(x, y) {
var z = x + y;
return z;
}
console.log(add(a, b));
JS引擎在程序開始執(zhí)行前會(huì)把它包裝成一個(gè)main函數(shù):
// 虛構(gòu)的main函數(shù)
function main() {
var a = 1;
var b = 2;
function add(x, y) {
var z = x + y;
return z;
}
console.log(add(a, b));
}
然后,調(diào)用這個(gè)main函數(shù):
main._current_scope_ = window; // 將全局作用域(對(duì)象)設(shè)為window main.call(window) // 將this指向window
4. 意義何在?
(1) JS也有了入口函數(shù)main,跟其他語言一致了。
(2) 省去了全局作用域的概念,或者說全局作用域也成了函數(shù)作用域。
(3) 通過上面對(duì)main函數(shù)的調(diào)用過程,可以明白全局作用域中的那些特殊性質(zhì)的由來。
(4) 最后一點(diǎn),將所有JS源碼當(dāng)成一個(gè)函數(shù),是為了后面講事件隊(duì)列、事件循環(huán)做鋪墊。
以上就是小編給大家介紹的JavaScript學(xué)習(xí)筆記(三):JavaScript也有入口Main函數(shù),希望大家喜歡。
- C++改變編程入口為main函數(shù)
- C語言之沒有main函數(shù)的helloworld示例
- c語言main函數(shù)使用及其參數(shù)介紹
- C語言main函數(shù)的參數(shù)及其返回值詳細(xì)解析
- C語言中怎么在main函數(shù)開始前執(zhí)行函數(shù)
- 深入探討:main函數(shù)執(zhí)行完畢后,是否可能會(huì)再執(zhí)行一段代碼?
- 深入Main函數(shù)中的參數(shù)argc,argv的使用詳解
- 解析在main函數(shù)之前調(diào)用函數(shù)以及對(duì)設(shè)計(jì)的作用詳解
- C#難點(diǎn)逐個(gè)擊破(4):main函數(shù)
- .NET中函數(shù)Main的使用技巧
相關(guān)文章
JavaScript 浮動(dòng)定位提示效果實(shí)現(xiàn)代碼
本來想做一個(gè)集合浮動(dòng)定位和鼠標(biāo)跟隨的tooltips效果,但發(fā)現(xiàn)定位和鼠標(biāo)跟隨在一些關(guān)鍵的地方還是不同的,還是分開來吧。2009-09-09
HTML5+Canvas調(diào)用手機(jī)拍照功能實(shí)現(xiàn)圖片上傳(下)
這篇文章主要為大家詳細(xì)介紹了HTML5+Canvas調(diào)用手機(jī)拍照功能實(shí)現(xiàn)圖片上傳,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04
原生js實(shí)現(xiàn)可兼容PC和移動(dòng)端的拖動(dòng)滑塊功能詳解【測(cè)試可用】
這篇文章主要介紹了原生js實(shí)現(xiàn)可兼容PC和移動(dòng)端的拖動(dòng)滑塊功能,結(jié)合實(shí)例形式詳細(xì)分析了javascript事件響應(yīng)及頁面元素屬性動(dòng)態(tài)操作實(shí)現(xiàn)滑塊拖動(dòng)功能的相關(guān)操作技巧,需要的朋友可以參考下2019-08-08
一個(gè)對(duì)于js this關(guān)鍵字的問題
一個(gè)對(duì)于js this關(guān)鍵字的問題...2007-01-01
如何使用瀏覽器擴(kuò)展篡改網(wǎng)頁中的JS?文件
這篇文章主要為大家介紹了如何使用瀏覽器擴(kuò)展篡改網(wǎng)頁中的JS文件實(shí)現(xiàn)解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05
舉例講解JavaScript substring()的使用方法
這篇文章主要通過舉例的方法講解了javaScript substring()的用法,substring() 方法用于提取字符串中介于兩個(gè)指定下標(biāo)之間的字符,感興趣的小伙伴們可以參考一下2015-11-11

