偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

JavaScript預(yù)解析處理過(guò)程原來(lái)是這回事

開發(fā) 前端
一般來(lái)說(shuō),Javascript代碼的執(zhí)行包括兩個(gè)過(guò)程:預(yù)解析處理過(guò)程 和 逐行解讀過(guò)程。

 講解

一般來(lái)說(shuō),Javascript代碼的執(zhí)行包括兩個(gè)過(guò)程:預(yù)解析處理過(guò)程 和 逐行解讀過(guò)程。在代碼逐行解讀前,Javasript引擎需要進(jìn)行代碼的預(yù)處理過(guò)程。預(yù)解析處理的工作主要是變量提升和給變量分配內(nèi)存,具體過(guò)程是在每個(gè)作用域中查找var聲明的變量、函數(shù)定義和命名函數(shù)(函數(shù)參數(shù)),找到它們后,在當(dāng)前作用域中給他們分配內(nèi)存,并給他們?cè)O(shè)置初始值。預(yù)解析設(shè)置的初始值分別是:對(duì)于var聲明的變量,初始值是undefined,對(duì)函數(shù)定義,變量名為函數(shù)名,函數(shù)變量的初始值為函數(shù)定義本身;對(duì)命名參數(shù),如果函數(shù)調(diào)用時(shí)沒有指定參數(shù)值,則命名參數(shù)的初始值為undefined,如果函數(shù)調(diào)用是指定了參數(shù)值,則命名參數(shù)的初始值為指定的參數(shù)值。

注:對(duì)于變量聲明的同時(shí)賦值的語(yǔ)句,例如:var a = 9,Javascript引擎對(duì)它進(jìn)行處理時(shí)把該語(yǔ)句分拆為兩條語(yǔ)句:var a和a=9,其中,var a在預(yù)解析階段進(jìn)行處理,a=9是賦值表達(dá)式,在逐行解讀階段進(jìn)行賦值。所以預(yù)解析中,不管變量聲明時(shí)是否有賦值,變量的初始值都是undefiend。

1.預(yù)解析發(fā)生的時(shí)機(jī)

(1)、遇到<script>標(biāo)簽時(shí)

瀏覽器加載到<script>標(biāo)簽時(shí),將使用javascript引擎對(duì)<script></script>標(biāo)簽對(duì)之間的代碼塊進(jìn)行預(yù)解析:找到函數(shù)定義和函數(shù)體外的所有var聲明的變量,并給它們分配內(nèi)存和設(shè)置初始值。

對(duì)同名的var變量和函數(shù)變量,只會(huì)分配一次棧內(nèi)存。但在堆內(nèi)存中會(huì)給函數(shù)變量的初始值分配內(nèi)存。對(duì)變量賦初始值時(shí),函數(shù)變量初始值優(yōu)先級(jí)高于var變量初始值,而同級(jí)別的函數(shù)變量,后定義的函數(shù)優(yōu)先于先定義的函數(shù)。

所以var變量名和函數(shù)變量名相同時(shí),如果內(nèi)存中的變量的值一開始為undefined,但最終內(nèi)存中該變量的初始值會(huì)替換為函數(shù)變量的值;否則變量的初始值保持不變。而同名的函數(shù)變量,后面定義的函數(shù)會(huì)替換前面定義的函數(shù)。

(2)、遇到函數(shù)時(shí)

每一對(duì)<script></script>標(biāo)簽中的代碼預(yù)解析完后會(huì)立即逐行解讀代碼。在解讀代碼的過(guò)程中,如果遇到函數(shù)調(diào)用,此時(shí)會(huì)在函數(shù)作用域中首先進(jìn)行預(yù)解析處理,預(yù)解析處理完才會(huì)執(zhí)行函數(shù)代碼。在函數(shù)作用域的預(yù)解析規(guī)則是:找到命名函數(shù)、所有var變量和函數(shù)定義,并給它們?cè)诤瘮?shù)作用域中分配內(nèi)存和設(shè)置初始值。對(duì)同名的var變量、命名參數(shù)和函數(shù)變量,只會(huì)分配一次棧內(nèi)存,但在堆內(nèi)存中會(huì)給函數(shù)變量的初始值分配內(nèi)存。對(duì)變量賦初始值時(shí),函數(shù)變量的值優(yōu)先級(jí)最高,其次是命名參數(shù)值。所以命名參數(shù)名和var變量名相同,內(nèi)存中變量的值是參數(shù)值;如果命名參數(shù)名和函數(shù)變量名相同或var變量名和函數(shù)變量名相同,內(nèi)存中變量的值為函數(shù)變量值。

2.頁(yè)面中包含多個(gè)<script></script>標(biāo)簽時(shí)的預(yù)解析

當(dāng)頁(yè)面中包含多個(gè)<script></script>標(biāo)簽時(shí),javascript引擎會(huì)按頁(yè)面中<script></script>標(biāo)簽出現(xiàn)的順序,從上往下對(duì)每一個(gè)<script></script>標(biāo)簽對(duì)之間的腳本代碼塊分別進(jìn)行預(yù)解析和逐行解讀處理。每一個(gè)<script></script>標(biāo)簽對(duì)之間代碼的預(yù)解析是全局范圍的,在函數(shù)調(diào)用時(shí)發(fā)上發(fā)生的函數(shù)代碼預(yù)解析則是針對(duì)函數(shù)范圍的。

需要注意的是,變量在預(yù)解析處理得到的初始值在逐行解讀代碼過(guò)程中會(huì)被賦值表達(dá)式(帶有=,+=,-=,*=,/=,++,--等運(yùn)算符號(hào)的語(yǔ)句)修改。

示例

我們通過(guò)幾個(gè)示例來(lái)詳細(xì)看一下。

預(yù)解析變量的優(yōu)先級(jí)示例:

  1. <script> 
  2. alert("(1)該行結(jié)果是:" + a)  // 1 
  3. var a = 3; // 2 
  4. alert("(2)該行結(jié)果是" + a) // 3 
  5. function a (){ // 4 
  6.  alert(2); 
  7. var a = 6; // 5 
  8. function a(){ // 6 
  9.  alert(4); 
  10. alert("(3)該行結(jié)果是"+ a); // 7  
  11. </script> 

彈出框結(jié)果分別為:

1處彈出的內(nèi)容:

  1. (1)該行結(jié)果是: 
  2. function a(){ 
  3.    alert(4); 

3處彈出的內(nèi)容:

  1. (2)該行結(jié)果是: 3 

7處彈出的內(nèi)容:

  1. (3)該行結(jié)果是: 6 

上述運(yùn)行結(jié)果正是預(yù)解析和逐行解讀分階段處理的結(jié)果。Javascript引擎遇到<script></script>標(biāo)簽時(shí),開始按代碼出現(xiàn)的順序進(jìn)行預(yù)解析處理:首先預(yù)解析注釋2處的var變量a,給它分配內(nèi)存,并給他賦初始值為"undefined";然后預(yù)解析注釋4處的函數(shù)變量a,發(fā)現(xiàn)該變量和已分配內(nèi)存的var變量同名,所以不再對(duì)函數(shù)變量a分配棧內(nèi)存,而只給它分配堆內(nèi)存存儲(chǔ)函數(shù)定義,同時(shí)會(huì)將棧內(nèi)存中的變量a的值修改為函數(shù)變量的初始值function a(){alert(2);};再接著預(yù)解析注釋5處的var變量a,該變量與前面預(yù)解析得到的函數(shù)變量a同名,所以對(duì)該變量也不再分配內(nèi)存,由于函數(shù)變量值優(yōu)先于var變量值,所以此時(shí)注釋5處的var變量a初始值undefined不會(huì)修改內(nèi)存變量的函數(shù)定義值;最后預(yù)解析注釋6處的函數(shù)變量a,發(fā)現(xiàn)它和內(nèi)存中的變量a同名,也不再給它分配內(nèi)存,但會(huì)在堆中分配內(nèi)存存儲(chǔ)6處的函數(shù)定義。由于后定義的函數(shù)優(yōu)先級(jí)高于前面定義的函數(shù),此時(shí)內(nèi)存的變量a的函數(shù)定義值被修改為function a(){alert(4);}。因此最終內(nèi)存中的變量a的初始值為function a(){alert(4)};。至此,預(yù)解析完成。

接著進(jìn)行逐行解讀代碼。在逐行解讀代碼階段,首先解讀到注釋1處代碼,此時(shí)會(huì)去內(nèi)存中查找變量a,如果找到,讀取變量a的值并輸出到警告對(duì)話框中;如果沒找到,將報(bào)a is not defined錯(cuò)誤。上面的預(yù)解析的結(jié)果是內(nèi)存中存在變量a,且其值為function a(){alert(4);}。注釋2處的代碼是一個(gè)賦值表達(dá)式:a=3,執(zhí)行該代碼后,會(huì)將內(nèi)存中的變量a的值修改為“3”。所以執(zhí)行到注釋3處代碼時(shí),從內(nèi)存中讀取到的值為“3”。注釋4處定義了一個(gè)函數(shù),執(zhí)行時(shí)會(huì)跳出函數(shù)定義不作任何操作。注釋5處代碼是一個(gè)賦值表達(dá)式:a=6,執(zhí)行該行代碼后,會(huì)將內(nèi)存中的變量a的值修改為“6”。注釋6處又是一個(gè)函數(shù)定義,不作解讀。最后執(zhí)行了注釋7處的代碼,從而讀取到值“6”。

 

責(zé)任編輯:姜華 來(lái)源: 前端歷劫之路
相關(guān)推薦

2018-06-04 08:40:20

磁盤分區(qū)MBR

2025-04-03 10:39:56

2021-07-29 16:56:59

微信騰訊注冊(cè)

2012-02-09 14:02:35

JavaScript

2022-08-15 08:01:00

三色標(biāo)記JVM算法

2020-06-30 08:12:32

VMwareKVMDocker

2021-11-12 08:07:31

SQL緩存RabbitMQ

2025-07-03 07:05:00

JavaScriptPromise代碼

2009-09-24 17:11:53

Hibernate處理

2017-06-06 15:13:07

2009-03-10 12:42:45

2010-06-09 18:17:20

Postfix郵件

2010-06-02 18:00:05

Postfix郵件

2022-12-14 07:32:40

InnoDBMySQL引擎

2021-02-07 08:13:18

@DateTimeFo@NumberFormSpring

2009-07-20 17:49:07

JSF請(qǐng)求處理

2022-05-05 08:55:12

工業(yè)物聯(lián)網(wǎng)IIoT

2024-02-06 09:30:25

Figma矩形矩形物理屬性

2020-02-23 15:55:00

疫情AI人工智能

2023-05-22 15:58:11

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)