js的預編譯和單執行緒是什麼?

2021-10-01 03:43:23 字數 4032 閱讀 6669

js是單執行緒的語言,也是一門解析型語言,所以他有著屬於自己的一種執行方式,我們所說我預編譯就是js解析型語言的一種解釋。所以我要先給大家描述一下js的語言分析和同步概念。

在我們**執行的時候,我們的瀏覽器會先將js所有需要執行的**全面檢測一遍,目的是排除低階的語法錯誤,檢測到錯誤後,乙個乙個丟擲,而不是一下子全部丟擲,所以js是單執行緒,這也是一種程式設計上的同步。

什麼是js的同步呢?

同步:從上往下按順序執行的程式; 弊端:中間任何乙個程式出現問題,下面**乙個都不會執行就像山間小路,乙個不能走了,下面全堵住了

var a =10;

var b =20;

console.

log(a)

console.

log(c)

// c 沒有定義,所以報錯,下面的 console.log(b) 就不會執行

console.

log(b)

來我們來看一下執行結果

什麼是js的非同步呢?

非同步(多個出口):程式的執行順序是無序的。不會存在等待現象,誰快是先執行

就像高速公路,有多條線,但還是只有乙個出口

console.

log(a)

var a =

10;

那麼他的輸出過結果呢?讓我們也來看一下

那麼大家有沒有一點奇怪呢?為什麼沒有報錯,我們上面說js是一門解析型語言,按道理來說是解析一行執行一行,那麼在我們輸出a的時候,a還是沒有定義的,所以他應該是會報錯的,這裡就要說到我們的預編譯環節了。

首先我們先來簡單的說一下變數提公升,它是屬於預編譯的一種,我先給大家混個眼熟,然後後面再給大家詳細講解。下面我先講解一下簡略版!這個是簡略版,大家且先看看:

將所有變數提公升當前作用域最頂端,賦值為undefined

將函式宣告提公升到作用域最頂端

當變數名與函式名重複的時候 , 變數賦值 會將函式本體覆蓋

console.

log(a)

;var a =10;

// 函式宣告

functiona(

) console.

log(a)

;

那麼下面的**再瀏覽器的解析中會這樣執行:

//首先將所有變數提公升當前作用域最頂端,賦值為undefined

var a = undefined;

// 將函式宣告提公升到作用域最頂端

functiona(

)// 當變數名與函式名重複的時候 , 變數賦值 會將函式本體覆蓋

console.

log(a)

;//所以a的就從一開始的undefined,變成 function a (){}

a =10;

console.

log(a)

;// 因為值賦是不會有提公升效果,所以最後執行賦值 a = 10

這樣是否就可以解決大家的困惑了呢?

我來總結一下那麼就是,①變數宣告提公升 ②函式宣告,如果有重名的就將其覆蓋,說到這裡我們就可以解決大部分基礎性問題了,但是我們講了就要將其講的透徹,他為什麼會是這樣的呢?

下面我就為大家來詳細講解預編譯!

預編譯存在於函式執行的前一刻!記住了,是函式執行的前一刻,大家先別去想上面的**,先記住我的這句話,因為上面的**講解是存在問題的,僅僅是為了讓大家了解一下什麼叫做變數提公升,函式宣告提公升 。

首先大家先看一下這四句話:

預編譯存在於函式執行的前一刻!

1 生成乙個ao 物件

2 將函式體中所有變數宣告和形參,作為ao物件的屬性名,提公升到作用域的最頂端,值為undefined

3 將實參值和形參相統一

4 在函式體中,找函式宣告,函式體賦予值(只有函式宣告才會提公升,表示式不會!!)

function

fun(x, y)

console.

log(a)

console.

log(b)

console.

log(x)

console.

log(y)

console.

log(c)

}fun(1,2)

我們看到fun()執行,也就是函式執行,那麼就再fun執行的前一刻會生成乙個ao物件(四句話的第一句)

所以ao物件再次變化

var a = undefined;

// 不變

var b = undefined;

// 不變

var x =1;

// 不變

var y =2;

// 不變

varc

=functionc(

)當所有的函式宣告找到,並且賦完值,那麼我們的預編譯的ao物件就執行完畢了

}

所以我們再來**上面的**:

function

fun(x, y)

}fun(1

,2)他就會變成:

function

fun(x, y)

// 因為var和函式表示式已經提公升了,但賦值沒有提公升,所以就變成下面這樣

console.

log(a)

// undefined

console.

log(b)

// undefined

console.

log(x)

// 1

console.

log(y)

// 2

console.

log(c)

// function c() {}

a =0;

b =0;

console.

log(a)

// 0

console.

log(b)

// 0

console.

log(x)

// 1

console.

log(y)

// 2

console.

log(c)

//function c() {}

}fun(1,2)

這樣就是預編譯的結束和**的執行的過程了,那麼我們再來講一下最上面的**:

console.

log(a)

;var a =10;

// 函式宣告

functiona(

) console.

log(a)

;

大家也可以將其看成乙個大的預編譯過程也就是go物件生成的過程流程:

第一步:生成乙個go物件

go{}

第二步:分析變數:go物件內容

go第三步:分析函宣告: go 如下

go(a:function a() {})

因為少了形參所以比上面的ao物件預編譯要少一步,所以如果大家僅僅把預編譯當成 變數提公升,函式宣告提公升 是明顯是不足夠的!!

希望大家看了之後有所感悟,並附上一道題,當大夥看完後可以自己去聯絡一番:

console.

log(a)

function

fun(a, b)if(

false

) console.

log(a)bb(

) console.

log(a)

}var a =

100fun(10

,20) console.

log(a)

js的單執行緒和預編譯是什麼?

js是單執行緒的語言,也是一門解析型語言,所以他有著屬於自己的一種執行方式,我們所說我預編譯就是js解析型語言的一種解釋。在我們 執行的時候,我們的瀏覽器會先將js所有需要執行的 全面檢測一遍,目的是排除低階的語法錯誤,檢測到錯誤後,乙個乙個丟擲,而不是一下子全部丟擲,所以js是單執行緒,這也是一種...

js的單執行緒和預編譯是什麼?

js是單執行緒的語言,也是一門解析型語言,所以他有著屬於自己的一種執行方式,我們所說我預編譯就是js解析型語言的一種解釋。語言分析 在我們 執行的時候,我們的瀏覽器會先將js所有需要執行的 全面檢測一遍,目的是排除低階的語法錯誤,檢測到錯誤後,乙個乙個丟擲,而不是一下子全部丟擲,所以js是單執行緒,...

JS非同步和單執行緒舉例

js 需要非同步的根本原因是 js 是單執行緒運 的,即在同 時間只能做 件事,不能 個 ajax 請求由於 絡 較慢,請求需要 5 秒鐘。如果是同步,這 5 秒鐘 就卡死在這 啥也做不了了。非同步的話,就好很多了,5 秒等待就等待了,其他事情不耽誤做,於那 5 秒鐘等待是 速太慢,不是因為 js ...