JavaScript 自由變數以及作用域鏈

2021-08-29 01:31:58 字數 1902 閱讀 1797

切入正題之前,我們先看一段**~

var x=10;

function fn()

function show(f))();

}show(fn)

注:(function(){})表示乙個匿名函式。function(arg)定義了乙個引數為arg的匿名函式,然後使用(function(arg))(param)來呼叫這個匿名函式。其中param是傳入這個匿名函式的引數。需要注意與$(function(){})的區別:$(function(){}) 是 $(document).ready(function(){}) 的簡寫,用來在dom載入完成之後執行一系列預先定義好的函式。

這裡我們就可以引入另乙個概念了:自由變數。

什麼叫自由變數呢?在a作用域中使用的變數x,卻沒有在a作用域中宣告(即在其他作用域中宣告的),對於a作用域來說,x就是乙個自由變數。

var x=10;

function fn()

上文中的x就是個自由變數。

那你們猜猜,這段**將在控制台輸出的數字是多少?

答案是——20!!!

啥?你也是這樣以為的?

嘿嘿,那你就錯了,上面我是逗你玩兒的。

正確答案是:10。

沒錯,正確答案就是10。

這是為什麼呢?其實,在呼叫乙個函式時,要到建立這個函式的那個作用域中取值——是「建立」,而不是「呼叫」,切記切記——其實這就是所謂的「靜態作用域」。

對於本文第一段**,在fn函式中,取自由變數x的值時,要到哪個作用域中取?——要到建立fn函式的那個作用域中取——無論fn函式將在**呼叫。

上面描述的只是跨一步作用域去尋找。

如果跨了一步,還沒找到呢?——接著跨!——一直跨到全域性作用域為止。要是在全域性作用域中都沒有找到,那就是真的沒有了。

這個一步一步「跨」的路線,我們稱之為——作用域鏈。

我們拿文字總結一下取自由變數時的這個「作用域鏈」過程:(假設a是自由量)

第一步,現在當前作用域查詢a,如果有則獲取並結束。如果沒有則繼續;

第二步,如果當前作用域是全域性作用域,則證明a未定義,結束;否則繼續;

第三步,(不是全域性作用域,那就是函式作用域)將建立該函式的作用域作為當前作用域;

第四步,跳轉到第一步。

好了,我們就拿這個按這個步驟來看看上面的**。

第一步,在當前作用域(即fn()函式域)查詢x,沒有找到.

第二步,在fn()作用域沒有找到x,則返回到建立fn的作用域去找,找到x=10,結束。

因此,控制台將輸出10。

到這裡大家獲取還是不夠清楚,那麼我們再舉乙個更複雜的例子。

阿福!關門!放**~~

var a=10;

function fn()

return b;

}var x=fn();

b=200;

x();

這段**,控制台會輸出什麼呢?

我們來分析一下:

第一步,fn()函式 return 回來的是函式b,則x=函式b。x()=b()。即執行b函式,b函式中有兩個變數,a和b。在b()中沒有a也沒有b,因此返回到建立b()函式的作用域繼續查詢,該作用域為fn()函式作用域。

第二步,在fn()作用域中,查詢到b=20,依舊沒有找到a。則返回到建立fn()的作用域去查詢。該作用域為全域性作用域。

第三步,在全域性作用域中,查詢到a=10,因此a+b=30。控制台輸出三十,結束。

biu~~~

高階js 變數提公升以及自由變數

q首先一道題 if false console.log a undefined 我以為輸出referenceerror aa is not defined 但是實際輸出undefined 因為js沒有塊級作用域,所以最後 就成了這樣 vara if false console.log a 1 let...

Javascript變數作用域

1.變數作用域是什麼鬼?2.全域性變數 全域性變數擁有全域性作用域 作用範圍在整個頁面中 在 的任何地方都有定義。擁有全域性作用域的情形 1 宣告在函式外部的變數。eg var a 全域性變數 function b 2 宣告變數時,缺少關鍵字var。eg function b 函式引數的變數 fun...

JavaScript 型別和變數

在程式語言中,能夠表示並且操作的型別叫資料型別,但我們需要將值儲存起來以備以後使用的時候,我們就需要將值儲存到乙個變數中。js中資料分為兩類 原始型別 primitive type 和物件型別 object type 原始型別資料報括數字 字串和布林值,並且js中有兩個特殊的原始值null 空 和u...