JavaScript代碼的運行原理


此文章是為了面試准備所做。

解析機制和預解析請參考 http://www.cnblogs.com/HPNiuYear/archive/2012/08/27/2657879.html

http://www.blogjava.net/JAVA-HE/archive/2010/10/09/334021.html

JS解析引擎 http://www.nowamagic.net/librarys/veda/detail/1579

JS是啥?
JavaScript是解釋執行的客戶端腳本語言,讀取一個語句就執行一個運行的時候動態解析執行的。動態語言。
JavaScript是一種基於對象和事件驅動並具有相對安全性的客戶端腳本語言。

JS打哪里來的?
Javascript是一種由Netscape的LiveScript發展而來的原型化繼承的面向對象的動態類型的區分大小寫的客戶端腳本語言,主要目的是為了解決服務器端語言,比如Perl,遺留的速度問題,為客戶提供更流暢的瀏覽效果。

JS干嘛用?
嵌入HTML的文件之中。主要應用不是作為系統擴展,而是實現一般的任務控制

JS執行原理(帶js代碼的HTML文件運行原理)?
1、客戶端請求某個網頁,即我們在上網時在地址欄中輸入某個網址,例如:http://xxx.xxx.com/index.html,瀏覽器接收到網址之后,向遠程web服務器發送請求報文。
2、web服務器響應請求,web服務器找到請求的頁面“index.html”,並將整個頁面包含javascript的腳本代碼作為相應內容,發送回客戶端機器
3、客戶端瀏覽器解釋並執行帶JS腳本的代碼,客戶端瀏覽器打開回應的網頁文件“index.html”內容,從上往下逐行讀取並顯示其中的html或者腳本代碼,根據解析完成的HTML標簽完成相應的動作(如:如果遇到IMG、SRC等時,向服務器進一步請求相應資源。)腳本是從服務器端下載到客戶端,然后在客戶端進行的,即不占用服務器端的資源,因此通過客戶端腳本,客戶端分擔了服務器的的任務,大大的減輕了服務器的壓力,從而間接地提升了服務器的性能
    3.1 當瀏覽器遇到第一個代碼段,即第一個<script> 標記的時候,瀏覽器會執行之間的javascript代碼。
        3.1.1 讀取第一個代碼段的內容
        3.1.2 詞法分析:解釋性語言沒有編譯成二進制代碼,但是要進入到運行階段,都應該是會經過詞法分析、語法分析生成語法樹。解釋性語言在生成語法樹后,就可以執行了。(這個跟腳本引擎編譯器有關)在這個過程中,有語法檢查(比如括號是否匹配),發現無法生成語法樹,則報錯,結束整個代碼塊的解析。
        3.1.3 預解析
            3.1.3.2 javascript在執行前會進行類似“預解析”的操作:首先會創建一個在當前執行環境下的活動對象,並將那些用var 聲明的變量、定義的函數設置為活動對象的屬性,但是此時這些變量的賦值都是undefined。
            3.1.3.3 在javascript解釋執行階段,遇到變量需要解析時,會首先從當前執行環境的活動對象中查找,如果沒有找到‍而且該執行環境的擁有者有prototype屬性時則會從prototype鏈中查找,否則將會按照作用域鏈查找。遇到var a = …這樣的語句時會給相應的變量進行賦值(注意:變量的賦值是在解釋執行階段完成的,如果在這之前使用變量,它的值會是undefined)。
        3.1.4 執行
    3.2 檢查是否還有下一段代碼?有就繼續,否則結束。
4. 將最終結果顯示在瀏覽器窗口中。

例如:
//首先客戶端發送請求:http://localhost:8080/index.html。實際上發送的數據是:step 1 - 2
GET /index.html HTTP/1.1
Accept: **
Referer: http://localhost:8080/index.html
Accept-Language: en,zh-cn;q=0.5
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (MSIE 7.0; MSIE 7.0; Windows NT 5.1; InfoPath.1)
Host: localhost:8080
Connection: Keep-Alive
//服務端把圖片在發送給客戶端。Step 3 - 4
//然后當他解析到新的特殊標簽<img 的時候,再次發送請求:Step 5
GET /images/logo.gif HTTP/1.1
Accept: */*
Referer: http://localhost:8080/index.html
Accept-Language: en,zh-cn;q=0.5
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (MSIE 7.0; MSIE 7.0; Windows NT 5.1; InfoPath.1)
Host: localhost:8080
Connection: Keep-Alive
//服務端把圖片在發送給客戶端。step 5-6


JS 注意事項?
1 JavaScript是解釋執行的客戶端腳本語言,讀取一個語句就執行一個。不需要經歷編譯和鏈接這些階段,大都直接解釋執行
2. 每個腳本定義的全局變量和函數,都可以被后面執行的腳本所調用。
3 變量的調用,必須是前面已經聲明,否則獲取的變量值是undefined。
4 Javascript里面都是對象,必須有一種機制,將所有對象聯系起來
5 以前的嚴格JS是以分號為語句的分隔符,但現在一些瀏覽器已經接受以換行符為分隔符(似乎是很多人喜歡用基於對象的編程了,而在JS中寫對象的函數是需要加分號的,所以很多人都愛忘)。
6 JS本身只提供語法解析與少部分內部函數支持,其他的均由宿主支持。比如在網頁JS中的window, document, navigator等對象,均是由瀏覽器提供基於其它語言的代碼,這些代碼通常被隱藏,但很大程度上決定了JS的運行效率。如果你有興趣,打開Chrome,按F12,調處Console,然后輸alert(注意沒有()),你就會發現[native code]這個東西。

 

常見問題:
瀏覽許多網站的時候,瀏覽器都會報JavaScript腳本錯誤,為什么JavaScript的函數還能運行呢?
其實它運行成功的是那些沒有錯誤的JavaScript函數而已,而且JavaScript加載編譯的時候,是以<script>遵守document加載html節點樹形加載的,所以是先加載的<Script>是會先運行的,但是在<script>標簽里面,但JavaScript遇到編譯錯誤的代碼行的時候就會報錯跳出這段<script>,所以之前沒有跳出<script>的時候加載的代碼段因為已經加載到document里面,所以是可以運行的:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM