JS 函式作用域(面試常考,還不來看)

2021-10-22 14:14:42 字數 4020 閱讀 7838

二、作用域上下級

三、作用域預解析講解

四、作用域預解析案例

全域性作用域是最大的作用域,包含了區域性作用域。在全域性作用域中定義的變數可以在如何地方使用

//下面兩個變數都是存在全域性作用域下面的,都是可以在任意地方使用的

var num1 =

100;

var num2 =

200;

區域性作用域就是在全域性作用域下面,開闢出來的乙個相對小一些的作用域。 在區域性作用域中定義的變數只能在這個區域性作用域內部使用

// 這個 num 是乙個全域性作用域下的變數 在任何地方都可以使用

var num =

100;

functionfn(

)fn()

;

// 全域性作用域下的 a

var a =

100;

functionfn(

)fn()

;console.

log(a)

;// 100

console.

log(b)

;// 報錯:b is not defined

首先,在自己的作用域內部查詢,如果有,就直接拿來使用

如果沒有,就去上一級作用域查詢,如果有,就拿來用

如果沒有,就進行去上一級作用域查詢,以此類推

如果一直到全域性作用域 window 都沒有這個變數,那麼就會直接報錯(該變數 is not defined)

var num =

100;

functionfn(

)fun()

;}fn(

);

functionfn(

)fn()

;console.

log(num)

;//發現自己作用域沒有,自己身處全域性作用域,就沒有上一級了,直接報錯

先在自己作用域內部查詢,有就直接賦值

沒有就去上一級作用域內部查詢,有就直接賦值

在沒有再去上一級作用域查詢,有就直接賦值

如果一直找到全域性作用域 window 都沒有,那麼就把這個變數定義為全域性變數,在給他賦值(不會報錯

functionfn(

)fn()

;console.

log(num1)

;// 報錯

function

fun(

)fun()

;console.

log(num2)

;// 200

//  全域性變數 num

var num;

functionfn(

) console.

log(num)

;// undefined

fun();

// 這個函式執行完後,才給 fn 私有變數 num 賦值

console.

log(num)

;// 100

}/*fun 呼叫以後,要給 num 賦值

檢視自己的作用域內部沒有 num 變數

就會向上一級查詢,上一級 fn 有 num 變數

那麼就會把 num 賦值給 fn 下的 num 變數

賦值後的 num,由於是 fn 的私有變數,所以不會再給全域性變數的 num 賦值了

*/console.

log(num)

;// undefinedfn(

);console.

log(num)

;// undefined

// 剛開啟頁面

var a =

100;

// 會被解析

functionfn(

)

// 剛開啟頁面

var a =

100;

// 會被解析

functionfn(

)fn()

;// 此時函式執行了,開始解析函式內部

var a =

100;

function

fn(b)b(

);}fn

(200

);

如果預解析在前面,形參在後面

這個 fn 函式執行的時候,先把 b 解析成為乙個 函式

然後再給 b 賦值為 200 ,那麼就會報錯了

如果預解析在後面,形參在前面

這個 fn 函式執行的時候,先把 b 賦值為乙個 200

然後預解析的時候,把 b 賦值為 函式,就不會報錯

結論:在函式執行的時候,先進行形參賦值,再進行預解析

var a = b =10;

a =10

;b =10;

console.

log(a)

;// 10

console.

log(b)

;// 10

**分析:

預解析:

1.var a;

**執行:

1. b =

20 此時變數賦值時,當一直到 window 都沒有 b 的時候,會把 b 定義為全域性變數

2. a = b

變數使用的是 b ,賦值的是 a

3. a =

10

var a = b;

// 在這裡直接報錯,程式中斷

a =10

;b =10;

console.

log(a)

;// 程式早就中斷,不執行

console.

log(b)

;// 程式早就中斷,不執行

**分析:

預解析:

1.var a;

**執行:

2. a = b

變數 使用 和 賦值

使用的是 b:b 沒有這個變數,所以直接報錯

賦值的是 a:

fn()

;var fn =

100;

functionfn(

)console.

log(fn)

;// 100

**分析:

預解析:

1.var fn

2.functionfn(

) 預解析結束的時候,fn 是乙個函式

**執行:

3.fn()

fn =

200 給全域性的 fn 賦值,賦值為200

4. fn =

100 給全域性的 fn 賦值,賦值為100

5. console.

log(fn)

100

fn()

;// 把全域性 fn 賦值為 200fn(

);// 把 200 當做乙個函式來執行,報錯

var fn =

100;

functionfn(

)console.

log(fn)

;// 程式早就中斷,不執行

functionfn(

)fun()

;}fn(

);

**分析:

fum內部 預解析:

1.var num;

**執行:

1. num = num;

使用的時候,num 就是 undefined

相當於給 num 變數,賦值為undefined

js函式作用域

js的變數作用域是函式級的,在js裡沒有類似c語言的塊級作用域。js程式設計環境的頂級作用域是window物件下的範圍,稱為全域性作用域,全域性作用域中的變數稱為全域性變數。js中的全域性變數相當於js中頂級作用域 window 的屬性。js函式內的變數無法在函式外面訪問,在函式內卻可以訪問函式外的...

巨集與內聯函式 面試常考)

第一部分 巨集 為什麼要使用巨集呢?因為函式的呼叫必須要將程式執行的順序轉移到函式所存放在記憶體中的某個地 址,將函式的程式內容執行完後,再返回到轉去執行該函式前的地方。這種轉移操作要求在轉去執行前要儲存現場並記憶執行的位址,轉回後要恢復現場,並按原來 儲存位址繼續執行。因此,函式呼叫要有一定的時間...

巨集與內聯函式 面試常考)

第一部分 巨集 為什麼要使用巨集呢?因為函式的呼叫必須要將程式執行的順序轉移到函式所存放在記憶體中的某個位址,將函式的程式內容執行完後,再返回到轉去執行該函式前的地方。這種轉移操作要求在轉去執行前要儲存現場並記憶執行的位址,轉回後要恢復現場,並按原來儲存位址繼續執行。因此,函式呼叫要有一定的時間和空...