1. <rp id="zsypk"></rp>

      2. 實用文檔>avascript的運行原理總結(jié)

        avascript的運行原理總結(jié)

        時間:2022-06-15 12:34:09

        avascript的運行原理總結(jié)

        avascript的運行原理總結(jié)

        avascript的運行原理總結(jié)

          1、按照html文檔流順序執(zhí)行javascript代碼

          瀏覽器是按照文檔流從上到下逐步解析頁面結(jié)構(gòu)和信息的,javascript代碼作為嵌入的腳本作為html文檔的組成部分,所以javascript代碼在加載時的執(zhí)行順序也是根據(jù)腳本標簽

          的出現(xiàn)順序來確定的。 如果通過腳本標簽的src屬性來引入外部.js文件,那么它也將按照其語句出現(xiàn)的順序來執(zhí)行,而且執(zhí)行過程是文檔加載的一部分。不會因為是外部js文件而延期執(zhí)行。 2、預(yù)編譯和執(zhí)行順序的關(guān)系 首先看如下這段代碼: function hello() {alert("hello");}hello();function hello() {alert("hello world");}hello();

          上面這段js代碼的輸出結(jié)果是hello world 、hello world,而不是先輸出hello,再輸出hello world。這是因為javascript并非完全按照順序來解釋執(zhí)行,而是在解釋之前會對javascript進行一次預(yù)編譯,在預(yù)編譯的過程中,會把定義式的函數(shù)優(yōu)先執(zhí)行,也會把所有var變量創(chuàng)建,默認值為undefined,以提高程序的執(zhí)行效率。也就是說上面的這段代碼其實被JS引擎預(yù)編譯成下面這樣:

          var hello = function() {alert("hello");};hello = function() {alert("hello world");};hello();hello();

          通過上面的代碼可以清晰的看到,函數(shù)其實也是變量,可以對函數(shù)進行賦值。為了防止前面那種情況的出現(xiàn),可以如下定義成兩個js文件:

          hello();function hello() {alert("hello");}// hello();

          function hello() {alert("hello world");}hello();

          上面第一個文件,我把hello()放在了function的前面,也是可以輸出正確結(jié)果的。

          hello();var hello = function() {alert("hello");};// hello();

          如果用上面的這種方法對function函數(shù)進行定義,那么就會報錯,報錯信息如下圖1所示:

          這里報錯hello is not a funtion,這是由于在預(yù)編譯的時候,對于用var聲明的變量,雖然最先就處理了,但是變量值是undefined。然后運行hello()的時候,由于前面的hello是undefined,類型沒有確定,所以這里是hello is not a function。雖然,程序中有定義這個函數(shù),但是定義的位置放在了調(diào)用的后面,那么調(diào)用的時候,程序并沒有運行到這里,所以沒用。

          再來看下面的這一段代碼:

          hello();function hello() {alert("hello");}// hello();

          上面的這段代碼雖然調(diào)用也是在函數(shù)定義的前面,但是這里是以function關(guān)鍵字來定義的,用function來定義的時候,跟var不一樣,function定義的時候就已經(jīng)把函數(shù)的值賦了過去,所以這里可以運行。

          2總結(jié):

          當(dāng)javascript引擎解析腳本時,它會在預(yù)編譯期對所有聲明的變量和函數(shù)進行處理。處理如下:

          (1)在執(zhí)行前會進行類似“預(yù)編譯”的操作:首先會創(chuàng)建一個當(dāng)前執(zhí)行環(huán)境下的活動對象,并將那些用var聲明的變量設(shè)置為活動對象的屬性,但是此時這些變量的賦值都是undefined,并將那些以function定義的函數(shù)也添加為活動對象的屬性,而且它們的值正是函數(shù)的定義。

          (2)在解釋執(zhí)行階段,遇到變量需要解析時,會首先從當(dāng)前執(zhí)行環(huán)境的活動對象中查找,如果沒有找到而且該執(zhí)行環(huán)境的擁有者有prototype屬性時則會從prototype鏈中查找,否則將會按照作用域鏈查找。遇到var a = ...這樣的語句時會給相應(yīng)的變量進行賦值(注意:變量的賦值是在解釋執(zhí)行階段完成的,如果在這之前使用變量,它的值會是undefined)。

          (3)綜上,一句話總結(jié)就是:變量的聲明在預(yù)編譯期,變量的初始化在運行期。

          alert(a); // 在預(yù)編譯期間a變量已經(jīng)加載,但是用var定義,所以賦值為undefined先,故這里輸出undefined。var a = 1; // 這里給前面的沒有賦值的a進行賦值為1alert(a); // 這里輸出的a已經(jīng)是前面賦值過的,所以輸出1。

          對于上面的這段代碼,輸出結(jié)果是:先輸出undefined,后輸出1,分析見代碼備注。

          雖然變量和函數(shù)聲明可以在文檔任意位置,但是良好的習(xí)慣應(yīng)該是在所有JavaScript代碼之前聲明全局變量和函數(shù),并對變量進行初始化賦值。在函數(shù)內(nèi)部也是先聲明變量,然后再引用。

          3、按塊執(zhí)行javascript代碼

          所謂代碼塊就是使用

          標簽分隔的代碼段。JavaScript解釋器在執(zhí)行腳本時,是按塊來執(zhí)行的。通俗地說,就是瀏覽器在解析HTML文檔流時,如果遇到一個標簽,則JavaScript解釋器會等到這個代碼塊都加載完后,先對代碼塊進行預(yù)編譯,然后再執(zhí)行。執(zhí)行完畢后,瀏覽器會繼續(xù)解析下面的HTML文檔流,同時JavaScript解釋器也準備好處理下一個代碼塊。由于JavaScript是按塊執(zhí)行的,所以如果在一個JavaScript塊中調(diào)用后面塊中聲明的變量或函數(shù)就會提示語法錯誤。 alert(a);

          var a = 1;

          上面的這段代碼,由于是兩個代碼塊,先執(zhí)行完第一個代碼塊,再執(zhí)行第二個代碼塊。執(zhí)行第一個代碼塊的時候,變量a沒有聲明,所以報錯,報錯信息是:a is not defined。

          var a = 1;

          alert(a);

          雖然說,JavaScript是按塊執(zhí)行的,但是不同塊都屬于同一個全局作用域,也就是說,塊之間的變量和函數(shù)是可以共享的。所以,上面的這兩個代碼塊運行的時候,雖然是兩個代碼塊,但是第一段運行以后,a變量就存在了全局作用域中,此時運行到第二個代碼塊,輸出的a變量就可以調(diào)用全局作用域中的a,所以沒有問題。

          4、借助事件機制改變javascript執(zhí)行順序

          由于JavaScript是按塊處理代碼,同時又遵循HTML文檔流的解析順序,所以在上面示例中會看到這樣的語法錯誤。但是當(dāng)文檔流加載完畢,如果再次訪問就不會出現(xiàn)這樣的錯誤。為了安全起見,我們一般在頁面初始化完畢之后才允許JavaScript代碼執(zhí)行,這樣可以避免網(wǎng)速對JavaScript執(zhí)行的影響,同時也避開了HTML文檔流對于JavaScript執(zhí)行的限制。

          window.onload = function() {alert(a);};

          var a = 1;alert("bb");

          alert("cc");

          windows.onload = function()表示先在觸發(fā)事件上加一個函數(shù),并不立即執(zhí)行,而是在整個頁面都加載完成以后再開始執(zhí)行該事件,及function。所以,在windows.onload執(zhí)行之前,就已經(jīng)把一些變量加載到了全局區(qū)中,所以沒有問題。上面的輸出結(jié)果是:先輸出bb,再輸出cc,最后輸出a。

          window.onload = function() {alert(a);};// 上面的onload不會執(zhí)行,只會執(zhí)行下面的onloadwindow.onload = function() {alert("onload2");};

          var a = 1;alert("bb");

          alert("cc");

          如果在一個頁面中存在多個windows.onload事件處理函數(shù),則只有最后一個才是有效的(如上面的代碼所示),為了解決這個問題,可以把所有腳本或調(diào)用函數(shù)都放在同一個onload事件處理函數(shù)中,如下面的代碼所示:

          window.onload = function() {// 放到一起alert(a);alert("onload2");};

          var a = 1;alert("bb");

          alert("cc");

          5、javascript輸出腳本的執(zhí)行順序

          在JavaScript開發(fā)中,經(jīng)常會使用document對象的write()方法輸出JavaScript腳本。document.write()方法先把輸出的腳本字符串寫入到腳本所在的文檔位置,瀏覽器在解析完document.write()所在文檔內(nèi)容后,繼續(xù)解析document.write()輸出的內(nèi)容,然后才按順序解析后面的HTML文檔。也就是說,JavaScript腳本輸出的代碼字符串會在輸出后馬上被執(zhí)行。請注意,使用document.write()方法輸出的JavaScript腳本字符串必須放在同時被輸出的

          標簽中,否則JavaScript解釋器因為不能夠識別這些合法的JavaScript代碼,而作為普通的字符串顯示在頁面文檔中。但是,通過document.write()方法輸出腳本并執(zhí)行也存在一定的風(fēng)險,因為不同JavaScript引擎對其執(zhí)行順序不同,同時不同瀏覽器在解析時也會出現(xiàn)Bug。

        【avascript的運行原理總結(jié)】相關(guān)文章:

        關(guān)于血糖檢測的原理總結(jié)03-09

        阿基米德原理教案(通用7篇)06-30

        計算機的組成原理教案(精選10篇)08-17

        靈芝的功效總結(jié)08-10

        電場公式總結(jié)06-08

        總結(jié)電熱的作用12-09

        祈使句的用法總結(jié)09-20

        唐朝文化總結(jié)04-20

        寒假體育總結(jié)01-22

        find的用法總結(jié)04-13

        用戶協(xié)議
        99热这里只有精品国产7_欧美色欲色综合色欲久久_中文字幕无码精品亚洲资源网久久_91热久久免费频精品无码
          1. <rp id="zsypk"></rp>