亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

探討JavaScript語(yǔ)句的執(zhí)行過(guò)程

 更新時(shí)間:2016年01月28日 14:29:39   投稿:mrr  
本文給大家介紹JavaScript語(yǔ)句的執(zhí)行過(guò)程的相關(guān)知識(shí),對(duì)js語(yǔ)句執(zhí)行過(guò)程的相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧

廢話不多說(shuō),直奔主題了。javascript的運(yùn)行原理總結(jié)如下:

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

瀏覽器是按照文檔流從上到下逐步解析頁(yè)面結(jié)構(gòu)和信息的,javascript代碼作為嵌入的腳本作為html文檔的組成部分,所以javascript代碼在加載時(shí)的執(zhí)行順序也是根據(jù)腳本標(biāo)簽<script>的出現(xiàn)順序來(lái)確定的。

如果通過(guò)腳本標(biāo)簽<script>的src屬性來(lái)引入外部.js文件,那么它也將按照其語(yǔ)句出現(xiàn)的順序來(lái)執(zhí)行,而且執(zhí)行過(guò)程是文檔加載的一部分。不會(huì)因?yàn)槭峭獠縥s文件而延期執(zhí)行。

2、預(yù)編譯和執(zhí)行順序的關(guān)系

首先看如下這段代碼:

<script type="text/javascript">
function hello() {
alert("hello");
}
hello();
function hello() {
alert("hello world");
}
hello();
</script>

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

<script type="text/javascript">
var hello = function() {
alert("hello");
};
hello = function() {
alert("hello world");
};
hello();
hello();
</script>

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

<script type="text/javascript">
hello();
function hello() {
alert("hello");
}
// hello();
</script>
<script type="text/javascript">
function hello() {
alert("hello world");
}
hello();
</script>

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

<script type="text/javascript">
hello();
var hello = function() {
alert("hello");
};
// hello();
</script>

如果用上面的這種方法對(duì)function函數(shù)進(jìn)行定義,那么就會(huì)報(bào)錯(cuò),報(bào)錯(cuò)信息如下圖1所示:

 

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

再來(lái)看下面的這一段代碼:

<script type="text/javascript">
hello();
function hello() {
alert("hello");
}
// hello();
</script>

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

總結(jié):

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

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

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

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

<script type="text/javascript">
alert(a); // 在預(yù)編譯期間a變量已經(jīng)加載,但是用var定義,所以賦值為undefined先,故這里輸出undefined。
var a = 1; // 這里給前面的沒(méi)有賦值的a進(jìn)行賦值為1
alert(a); // 這里輸出的a已經(jīng)是前面賦值過(guò)的,所以輸出1。
</script>

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

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

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

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

<script>
alert(a);
</script>
<script>
var a = 1;
</script>

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

<script>
var a = 1;
</script>
<script>
alert(a);
</script>

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

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

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

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>javascript</title>
<script>
window.onload = function() {
alert(a);
};
</script>
<script>
var a = 1;
alert("bb");
</script>
</head>
<body>
</body>
<script>
alert("cc");
</script>
</html>

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

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>javascript</title>
<script>
window.onload = function() {
alert(a);
};
// 上面的onload不會(huì)執(zhí)行,只會(huì)執(zhí)行下面的onload
window.onload = function() {
alert("onload2");
};
</script>
<script>
var a = 1;
alert("bb");
</script>
</head>
<body>
</body>
<script>
alert("cc");
</script>
</html>

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

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>javascript</title>
<script>
window.onload = function() {
// 放到一起
alert(a);
alert("onload2");
};
</script>
<script>
var a = 1;
alert("bb");
</script>
</head>
<body>
</body>
<script>
alert("cc");
</script>
</html>

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

在JavaScript開(kāi)發(fā)中,經(jīng)常會(huì)使用document對(duì)象的write()方法輸出JavaScript腳本。document.write()方法先把輸出的腳本字符串寫入到腳本所在的文檔位置,瀏覽器在解析完document.write()所在文檔內(nèi)容后,繼續(xù)解析document.write()輸出的內(nèi)容,然后才按順序解析后面的HTML文檔。也就是說(shuō),JavaScript腳本輸出的代碼字符串會(huì)在輸出后馬上被執(zhí)行。請(qǐng)注意,使用document.write()方法輸出的JavaScript腳本字符串必須放在同時(shí)被輸出的<script>標(biāo)簽中,否則JavaScript解釋器因?yàn)椴荒軌蜃R(shí)別這些合法的JavaScript代碼,而作為普通的字符串顯示在頁(yè)面文檔中。但是,通過(guò)document.write()方法輸出腳本并執(zhí)行也存在一定的風(fēng)險(xiǎn),因?yàn)椴煌琂avaScript引擎對(duì)其執(zhí)行順序不同,同時(shí)不同瀏覽器在解析時(shí)也會(huì)出現(xiàn)Bug。

以上所述是小編給大家介紹的JavaScript語(yǔ)句的執(zhí)行過(guò)程,希望對(duì)大家有所幫助。

相關(guān)文章

  • JavaScript中的class類詳解

    JavaScript中的class類詳解

    JavaScript?中的類(Class)是一種新的語(yǔ)言特性,它讓我們可以使用面向?qū)ο缶幊痰乃枷雭?lái)更加方便地組織和管理代碼。在本文中,我們將詳細(xì)介紹?JavaScript?中的類特性,感興趣的同學(xué)可以借鑒閱讀
    2023-05-05
  • JS閉包用法實(shí)例分析

    JS閉包用法實(shí)例分析

    這篇文章主要介紹了JS閉包用法,結(jié)合具體實(shí)例形式分析了javascript閉包的原理、執(zhí)行步驟與相關(guān)操作技巧,需要的朋友可以參考下
    2017-03-03
  • 使用apply方法實(shí)現(xiàn)javascript中的對(duì)象繼承

    使用apply方法實(shí)現(xiàn)javascript中的對(duì)象繼承

    javascript中的對(duì)象繼承的方法有很多,在接下來(lái)的文章中為大家介紹下使用apply方法是如何實(shí)現(xiàn)的
    2013-12-12
  • HTTP?302?redirect應(yīng)用及介紹

    HTTP?302?redirect應(yīng)用及介紹

    這篇文章主要為大家介紹了HTTP?302?redirect應(yīng)用及作用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • Promise對(duì)象all與race方法手寫示例

    Promise對(duì)象all與race方法手寫示例

    這篇文章主要為大家介紹了Promise對(duì)象all與race方法手寫示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • JavaScript實(shí)現(xiàn)動(dòng)態(tài)生成表格

    JavaScript實(shí)現(xiàn)動(dòng)態(tài)生成表格

    這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)動(dòng)態(tài)生成表格,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-08-08
  • JavaScript學(xué)習(xí)筆記之?dāng)?shù)組的增、刪、改、查

    JavaScript學(xué)習(xí)筆記之?dāng)?shù)組的增、刪、改、查

    這篇文章主要介紹了JavaScript學(xué)習(xí)筆記之?dāng)?shù)組的增、刪、改、查的相關(guān)資料,需要的朋友可以參考下
    2016-03-03
  • bootstrap網(wǎng)格系統(tǒng)使用方法解析

    bootstrap網(wǎng)格系統(tǒng)使用方法解析

    這篇文章主要為大家詳細(xì)解析了bootstrap網(wǎng)絡(luò)系統(tǒng)使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • 使用JavaScript實(shí)現(xiàn)響應(yīng)式計(jì)數(shù)器動(dòng)畫

    使用JavaScript實(shí)現(xiàn)響應(yīng)式計(jì)數(shù)器動(dòng)畫

    在本文中,我們將學(xué)習(xí)如何使用?HTML?CSS?和?JavaScript創(chuàng)建響應(yīng)式計(jì)數(shù)器動(dòng)畫。?我們?cè)诤芏嗟胤蕉伎梢杂?,比如適用于不同類型的個(gè)人網(wǎng)站、企業(yè)網(wǎng)站等,感興趣的可以了解一下
    2022-08-08
  • 詳解js對(duì)象中屬性的兩種類型之?dāng)?shù)據(jù)屬性和訪問(wèn)器屬性

    詳解js對(duì)象中屬性的兩種類型之?dāng)?shù)據(jù)屬性和訪問(wèn)器屬性

    在理解vue底層響應(yīng)式原理時(shí),了解到,原來(lái)對(duì)象中的屬性,不單單從表面看起來(lái)那么簡(jiǎn)單是key:value形式,而是還有隱藏的內(nèi)部特性,其中對(duì)象內(nèi)的屬性分為兩種類型的屬性:數(shù)據(jù)屬性和訪問(wèn)器屬性,本文將給大家詳細(xì)介紹一下數(shù)據(jù)屬性和訪問(wèn)器屬性,需要的朋友可以參考下
    2023-05-05

最新評(píng)論