js保證代碼執行的先後順序(js保證代碼執行的先後順序是什麼)

本文目錄一覽:

請問如何能讓js代碼按順序執行

js是單線程的語言,你這個代碼肯定是從商往下執行的,只不過刷新還沒有完成的時候,他還是可以繼續執行js的,也就是說,這中間有一個空檔期

如何確保JavaScript的執行順序

這篇帖子詳細的介紹了javascript的執行順序 希望對你有用 望採納 在這貼出帖子內容

1.1

按HTML文檔流順序執行JavaScript代碼

首先,讀者應該清楚,HTML文檔在瀏覽器中的解析過程是這樣的:瀏覽器是按着文檔流從上到下逐步解析頁面結構和信息的。JavaScript代碼作為嵌入的腳本應該也算做HTML文檔的組成部分,所以JavaScript代碼在裝載時的執行順序也是根據腳本標籤script的出現順序來確定的。例如,瀏覽下面文檔頁面,你會看到代碼是從上到下逐步被解析的。

複製代碼

代碼如下:

script

alert(“頂部腳本”);

/script

htmlhead

script

alert(“頭部腳本”);

/script

title/title

/head

body

script

alert(“頁面腳本”);

/script

/body/html

script

alert(“底部腳本”);

/script

如果通過腳本標籤script的src屬性導入外部JavaScript文件腳本,那麼它也將按照其語句出現的順序來執行,而且執行過程是文檔裝載的一部分。不會因為是外部JavaScript文件而延期執行。例如,把上面文檔中的頭部和主體區域的腳本移到外部JavaScript文件中,然後通過src屬性導入。繼續預覽頁面文檔,你會看到相同的執行順序。

複製代碼

代碼如下:

script

alert(“頂部腳本”);

/script

html

head

script src=””/script

title/title

/head

body

script src=””/script

/body

/html

script

alert(“底部腳本”);

/script

1.2 預編譯與執行順序的關係

在Javascript中,function才是Javascript的第一型。當我們寫下一段函數時,其實不過是建立了一個function類型的實體。

就像我們可以寫成這樣的形式一樣:

複製代碼

代碼如下:

functionHello()

{

alert(“Hello”);

}

Hello();

varHello = function()

{

alert(“Hello”);

}

Hello();

其實都是一樣的。 但是當我們對其中的函數進行修改時,會發現很奇怪的問題。

複製代碼

代碼如下:

scripttype=”text/javascript”

functionHello() {

alert(“Hello”);

}

Hello();

functionHello() {

alert(“Hello World”);

}

Hello();

/script

我們會看到這樣的結果:連續輸出了兩次Hello

World。

而非我們想像中的Hello和Hello World。

這是因為Javascript並非完全的按順序解釋執行,而是在解釋之前會對Javascript進行一次「預編譯」,在預編譯的過程中,會把定義式的函數優先執行,也會把所有var變量創建,默認值為undefined,以提高程序的執行效率。

也就是說上面的一段代碼其實被JS引擎預編譯為這樣的形式:

複製代碼

代碼如下:

scripttype=”text/javascript”

varHello = function() {

alert(“Hello”);

}

Hello = function() {

alert(“Hello World”);

}

Hello();

Hello();

/script

我們可以通過上面的代碼很清晰地看到,其實函數也是數據,也是變量,我們也可以對「函數「進行賦值(重賦值)。

當然,我們為了防止這樣的情況,也可以這樣:

複製代碼

代碼如下:

scripttype=”text/javascript”

functionHello() {

alert(“Hello”);

}

Hello();

/script

scripttype=”text/javascript”

functionHello() {

alert(“Hello World”);

}

Hello();

/script

這樣,程序被分成了兩段,JS引擎也就不會把他們放到一起了。

當JavaScript引擎解析腳本時,它會在預編譯期對所有聲明的變量和函數進行處理。

做如下處理:

1.

在執行前會進行類似「預編譯」的操作:首先會創建一個當前執行環境下的活動對象,並將那些用var申明的變量設置為活動對象的屬性,但是此時這些變量的賦值都是undefined,並將那些以function定義的函數也添加為活動對象的屬性,而且它們的值正是函數的定義。

2.

在解釋執行階段,遇到變量需要解析時,會首先從當前執行環境的活動對象中查找,如果沒有找到而且該執行環境的擁有者有prototype屬性時則會從prototype鏈中查找,否則將會按照作用域鏈查找。遇到var

a = …這樣的語句時會給相應的變量進行賦值(注意:變量的賦值是在解釋執行階段完成的,如果在這之前使用變量,它的值會是undefined)

所以,就會出現當JavaScript解釋器執行下面腳本時不會報錯:

複製代碼

代碼如下:

alert(a); //

返回值undefined

var a =1;

alert(a); //

返回值1

由於變量聲明是在預編譯期被處理的,所以在執行期間對於所有代碼來說,都是可見的。但是,你也會看到,執行上面代碼,提示的值是undefined,而不是1。這是因為,變量初始化過程發生在執行期,而不是預編譯期。在執行期,JavaScript解釋器是按着代碼先後順序進行解析的,如果在前面代碼行中沒有為變量賦值,則JavaScript解釋器會使用默認值undefined。由於在第二行中為變量a賦值了,所以在第三行代碼中會提示變量a的值為1,而不是undefined。

同理,下面示例在函數聲明前調用函數也是合法的,並能夠被正確解析,所以返回值為1。

複製代碼

代碼如下:

f(); //

調用函數,返回值1

function f(){

alert(1);

}

但是,如果按下面方式定義函數,則JavaScript解釋器會提示語法錯誤。

複製代碼

代碼如下:

f(); //

調用函數,返回語法錯誤

var f = function(){

alert(1);

}

這是因為,上面示例中定義的函數僅作為值賦值給變量f,所以在預編譯期,JavaScript解釋器只能夠為聲明變量f進行處理,而對於變量f的值,只能等到執行期時按順序進行賦值,自然就會出現語法錯誤,提示找不到對象f。

再見一些例子:

複製代碼

代碼如下:

script type=”text/javascript”

/*在預編譯過程中func是window環境下的活動對象中的一個屬性,值是一個函數,覆蓋了undefined值*/

alert(func); //function func(){alert(“hello!”)}

var func = “this is a variable”

function func(){

alert(“hello!”)

}

/*在執行過程中遇到了var重新賦值為”this is a variable”*/

alert(func); //this is a variable

/script

複製代碼

代碼如下:

script type=”text/javascript”

var name = “feng”; function func()

{

/*首先,在func環境內先把name賦值為undefined,然後在執行過程中先尋找func環境下的活動對象的name屬性,此時之前已經預編譯值為undefined,所以輸出是undefined,而不是feng*/

alert(name); //undefined var name = “JSF”;

alert(name); //JSF

}

func();

alert(name);

//feng

/script

雖然變量和函數聲明可以在文檔任意位置,但是良好的習慣應該是在所有JavaScript代碼之前聲明全局變量和函數,並對變量進行初始化賦值。在函數內部也是先聲明變量,然後再引用。

1.3 按塊執行JavaScript代碼

所謂代碼塊就是使用script標籤分隔的代碼段。例如,下面兩個script標籤分別代表兩個JavaScript代碼塊。

複製代碼

代碼如下:

script

// JavaScript代碼塊1

var a =1;

/script

script

// JavaScript代碼塊2

function f(){

alert(1);

}

/script

JavaScript解釋器在執行腳本時,是按塊來執行的。通俗地說,就是瀏覽器在解析HTML文檔流時,如果遇到一個script標籤,則JavaScript解釋器會等到這個代碼塊都加載完後,先對代碼塊進行預編譯,然後再執行。執行完畢後,瀏覽器會繼續解析下面的HTML文檔流,同時JavaScript解釋器也準備好處理下一個代碼塊。

由於JavaScript是按塊執行的,所以如果在一個JavaScript塊中調用後面塊中聲明的變量或函數就會提示語法錯誤。例如,當JavaScript解釋器執行下面代碼時就會提示語法錯誤,顯示變量a未定義,對象f找不到。

複製代碼

代碼如下:

script

// JavaScript代碼塊1

alert(a);

f();

/script

script

// JavaScript代碼塊2

var a =1;

function f(){

alert(1);

}

/script

雖然說,JavaScript是按塊執行的,但是不同塊都屬於同一個全局作用域,也就是說,塊之間的變量和函數是可以共享的。

1.4 藉助事件機制改變JavaScript執行順序

由於JavaScript是按塊處理代碼,同時又遵循HTML文檔流的解析順序,所以在上面示例中會看到這樣的語法錯誤。但是當文檔流加載完畢,如果再次訪問就不會出現這樣的錯誤。例如,把訪問第2塊代碼中的變量和函數的代碼放在頁面初始化事件函數中,就不會出現語法錯誤了。

複製代碼

代碼如下:

script

// JavaScript代碼塊1

window.onload = function(){ // 頁面初始化事件處理函數

alert(a);

f();

}

/script

script

// JavaScript代碼塊2

var a =1;

function f(){

alert(1);

}

/script

為了安全起見,我們一般在頁面初始化完畢之後才允許JavaScript代碼執行,這樣可以避免網速對JavaScript執行的影響,同時也避開了HTML文檔流對於JavaScript執行的限制。

注意

如果在一個頁面中存在多個windows.onload事件處理函數,則只有最後一個才是有效的,為了解決這個問題,可以把所有腳本或調用函數都放在同一個onload事件處理函數中,例如:

複製代碼

代碼如下:

window.onload = function(){

f1();

f2();

f3();

}

而且通過這種方式可以改變函數的執行順序,方法是:簡單地調整onload事件處理函數中調用函數的排列順序。

除了頁面初始化事件外,我們還可以通過各種交互事件來改變JavaScript代碼的執行順序,如鼠標事件、鍵盤事件及時鐘觸發器等方法,詳細講解請參閱第14章的內容。

1.5 JavaScript輸出腳本的執行順序

在JavaScript開發中,經常會使用document對象的write()方法輸出JavaScript腳本。那麼這些動態輸出的腳本是如何執行的呢?例如:

複製代碼

代碼如下:

document.write(‘script

type=”text/javascript”‘);

document.write(‘f();’);

document.write(‘function f(){‘);

document.write(‘alert(1);’);

document.write(‘}’);

document.write(‘/script’);

運行上面代碼,我們會發現:document.write()方法先把輸出的腳本字符串寫入到腳本所在的文檔位置,瀏覽器在解析完document.write()所在文檔內容後,繼續解析document.write()輸出的內容,然後才按順序解析後面的HTML文檔。也就是說,JavaScript腳本輸出的代碼字符串會在輸出後馬上被執行。

請注意,使用document.write()方法輸出的JavaScript腳本字符串必須放在同時被輸出的script標籤中,否則JavaScript解釋器因為不能夠識別這些合法的JavaScript代碼,而作為普通的字符串顯示在頁面文檔中。例如,下面的代碼就會把JavaScript代碼顯示出來,而不是執行它。

複製代碼

代碼如下:

document.write(‘f();’);

document.write(‘function f(){‘);

document.write(‘alert(1);’);

document.write(‘);’);

但是,通過document.write()方法輸出腳本並執行也存在一定的風險,因為不同JavaScript引擎對其執行順序不同,同時不同瀏覽器在解析時也會出現Bug。

Ø 問題一,找不到通過document.write()方法導入的外部JavaScript文件中聲明的變量或函數。例如,看下面示例代碼。

複製代碼

代碼如下:

document.write(‘script

type=”text/javascript” src=””

/script’);

document.write(‘script type=”text/javascript”‘);

document.write(‘alert(n);’); // IE提示找不到變量n

document.write(‘/script’);

alert(n+1); // 所有瀏覽器都會提示找不到變量n

外部JavaScript文件(test.js)的代碼如下:

複製代碼

代碼如下:

var n =

1;

分別在不同瀏覽器中進行測試,會發現提示語法錯誤,找不到變量n。也就是說,如果在JavaScript代碼塊中訪問本代碼塊中使用document.write()方法輸出的腳本中導入的外部JavaScript文件所包含的變量,會顯示語法錯誤。同時,如果在IE瀏覽器中,不僅在腳本中,而且在輸出的腳本中也會提示找不到輸出的導入外部JavaScript文件的變量(表述有點長和繞,不懂的讀者可以嘗試運行上面代碼即可明白)。

Ø 問題二,不同JavaScript引擎對輸出的外部導入腳本的執行順序略有不同。例如,看下面示例代碼。

複製代碼

代碼如下:

script type=”text/javascript”

document.write(‘script type=”text/javascript”

src=””

/script’);

document.write(‘script type=”text/javascript”‘);

document.write(‘alert(2);’)

document.write(‘alert(n+2);’);

document.write(‘/script’);

/script

script type=”text/javascript”

alert(n+3);

/script

外部JavaScript文件(test1.js)的代碼如下所示。

複製代碼

代碼如下:

var n = 1;

alert(n);

在IE瀏覽器中的執行順序如圖1-6所示。

圖1-6 IE 7瀏覽器的執行順序和提示的語法錯誤

在符合DOM標準的瀏覽器中的執行順序與IE瀏覽器不同,且沒有語法錯誤,如圖1-7所示的是在Firefox 3.0瀏覽器中的執行順序。

圖1-7 Firefox 3瀏覽器的執行順序和提示的語法錯誤

解決不同瀏覽器存在的不同執行順序,以及可能存在Bug。我們可以把凡是使用輸出腳本導入的外部文件,都放在獨立的代碼塊中,這樣根據上面介紹的JavaScript代碼塊執行順序,就可以避免這個問題。例如,針對上面示例,可以這樣設計:

複製代碼

代碼如下:

script type=”text/javascript”

document.write(‘script type=”text/javascript”

src=””/script’);

/script

script type=”text/javascript”

document.write(‘script type=”text/javascript”‘);

document.write(‘alert(2);’) ; // 提示2

document.write(‘alert(n+2);’); // 提示3

document.write(‘/script’);

alert(n+3); // 提示4

/script

script type=”text/javascript”

alert(n+4); // 提示5

/script

這樣在不同瀏覽器中都能夠按順序執行上面代碼,且輸出順序都是1、2、3、4和5。存在問題的原因是:輸出導入的腳本與當前JavaScript代碼塊之間的矛盾。如果單獨輸出就不會發生衝突了。

js 怎麼讓方法執行有先後順序

1、定義幾個方法

2、依次執行函數,代碼寫在前面的先執行,寫在後面的後執行

示例:

function f1(){//定義f1函數

}

function f2(){//定義f2函數

}

f1();//先執行f1函數

f2();//再執行f2函數

js代碼執行順序的問題

JS變量提升問題,顧名思義,就是把下面的東西提到上面。具體資料可以百度搜索,

var t = 1;

function con(){

    console.log(t);//在函數內部,有變量提升

    var t = 2;

    console.log(t);

}

con();

變為如下:

var t = 1;

function con(){

    var t;

    console.log(t);//在函數內部,有變量提升

    t = 2;

    console.log(t);

}

con();

如果想要改變t變量的值,那麼在函數內部就不要定義x變量

var t = 1;

function con(){

    console.log(t);//1

    t = 2;

    console.log(t);//2

}

con();

js執行順序

你現在是先定義了函數a,然後定義了函數b,然後再去執行函數a

即使你把代碼改成這樣依舊能夠正常運行

a();

function a() {

    b();

}

function b() {

    console.log(111)

}

因為JS運行環境會把定義的代碼(變量/函數)提升到作用域的最前面

JavaScript預編譯與執行順序的關係

按照代碼塊的先後順序關係,先對代碼塊進行預編譯,再執行。代碼塊指的是script標籤包含的js片段。具體如下:

step 1. 讀入第一個代碼塊。

step 2. 做語法分析,有錯則報語法錯誤(比如括號不匹配等),並跳轉到step5。

step 3. 對var變量和function定義做「預編譯處理」(永遠不會報錯的,因為只解析正確的聲明)。

step 4. 執行代碼段,有錯則報錯(比如變量未定義)。

step 5. 如果還有下一個代碼段,則讀入下一個代碼段,重複step2。

step6. 結束。

原創文章,作者:N12O4,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/127827.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
N12O4的頭像N12O4
上一篇 2024-10-03 23:16
下一篇 2024-10-03 23:16

相關推薦

  • Python周杰倫代碼用法介紹

    本文將從多個方面對Python周杰倫代碼進行詳細的闡述。 一、代碼介紹 from urllib.request import urlopen from bs4 import Bea…

    編程 2025-04-29
  • JS Proxy(array)用法介紹

    JS Proxy(array)可以說是ES6中非常重要的一個特性,它可以代理一個數組,監聽數據變化並進行攔截、處理。在實際開發中,使用Proxy(array)可以方便地實現數據的監…

    編程 2025-04-29
  • Python字符串寬度不限制怎麼打代碼

    本文將為大家詳細介紹Python字符串寬度不限制時如何打代碼的幾個方面。 一、保持代碼風格的統一 在Python字符串寬度不限制的情況下,我們可以寫出很長很長的一行代碼。但是,為了…

    編程 2025-04-29
  • Python基礎代碼用法介紹

    本文將從多個方面對Python基礎代碼進行解析和詳細闡述,力求讓讀者深刻理解Python基礎代碼。通過本文的學習,相信大家對Python的學習和應用會更加輕鬆和高效。 一、變量和數…

    編程 2025-04-29
  • Python滿天星代碼:讓編程變得更加簡單

    本文將從多個方面詳細闡述Python滿天星代碼,為大家介紹它的優點以及如何在編程中使用。無論是剛剛接觸編程還是資深程序員,都能從中獲得一定的收穫。 一、簡介 Python滿天星代碼…

    編程 2025-04-29
  • 倉庫管理系統代碼設計Python

    這篇文章將詳細探討如何設計一個基於Python的倉庫管理系統。 一、基本需求 在着手設計之前,我們首先需要確定倉庫管理系統的基本需求。 我們可以將需求分為以下幾個方面: 1、庫存管…

    編程 2025-04-29
  • 寫代碼新手教程

    本文將從語言選擇、學習方法、編碼規範以及常見問題解答等多個方面,為編程新手提供實用、簡明的教程。 一、語言選擇 作為編程新手,選擇一門編程語言是很關鍵的一步。以下是幾個有代表性的編…

    編程 2025-04-29
  • Python實現簡易心形代碼

    在這個文章中,我們將會介紹如何用Python語言編寫一個非常簡單的代碼來生成一個心形圖案。我們將會從安裝Python開始介紹,逐步深入了解如何實現這一任務。 一、安裝Python …

    編程 2025-04-29
  • 怎麼寫不影響Python運行的長段代碼

    在Python編程的過程中,我們不可避免地需要編寫一些長段代碼,包括函數、類、複雜的控制語句等等。在編寫這些代碼時,我們需要考慮代碼可讀性、易用性以及對Python運行性能的影響。…

    編程 2025-04-29
  • 北化教務管理系統介紹及開發代碼示例

    本文將從多個方面對北化教務管理系統進行介紹及開發代碼示例,幫助開發者更好地理解和應用該系統。 一、項目介紹 北化教務管理系統是一款針對高校學生和教職工的綜合信息管理系統。系統實現的…

    編程 2025-04-29

發表回復

登錄後才能評論