js作用域和詞法分析

2022-07-12 07:45:13 字數 1454 閱讀 6227

都知道js中不存在類似於c++等語言的塊級作用域,例如for迴圈中定義的變數,其實是屬於當前物件下的屬性,同一物件下可以隨便訪問。只有函式可以限定乙個變數的作用範圍,即函式才是變數的作用域。

對於函式的變數訪問時遵循作用域鏈的,即當前函式執行時會有乙個當前作用域,當飲用某個變數時,會先查詢當前作用域內是否存在該變數的定義,如果不存在則根據作用域鏈向上去查詢父函式的作用域,有則拿來使用,沒有則繼續向上直到全域性作用域。關於作用域鏈這裡就不仔細描述,簡單而言,類似原型鏈,從全域性函式直到當前函式的作用域存在一種相互包含的關係,子可以向上訪問,但是父不可以向下訪問子函式的變數,這樣層層巢狀的關係鏈。

類似這樣的:

var num = 10;

function

a ()

a()

//結果alert(10),a裡沒有num所以向上查詢外層的作用域,有且等於10所以彈出10而不是undefined.

但是,下面的**就是undefined了:

var num = 10;

var num = 10;

function

a ()

為什麼呢? a()執行時雖然num=11沒有賦值但是父級作用域裡是有num=10的,不應該是undefined呀,js是按順序執行的,此時的var num = 11;根本沒有執行,所以應該是10!!你是不是也是這麼認為的,就和我當初一樣。。

2,分析變數宣告:如果有類似var a  之類的宣告,若沒有該屬性則增加屬性,若已存在則不做操作。預設為undefined。變數的賦值在執行階段才進行,即執行到該變數的時候才有 var a = 11

3,分析函式宣告:類似 function a(){},若當前活動物件沒有該屬性則新增否則重寫該屬性為方法a。

所以回到開始的那段**:

var num = 10;

function

a ()

}

具體步驟:1,分析形參: 此處無形參則不進行操作;當有形參時:

function

a (b)

a(4);

1,分析形參:則當前活動物件object.b = undefined; =>傳入引數4則:object.b = 4;

2,分析變數宣告:  var num 則object.num = undefined;

3, 分析函式宣告: function b(){} 則object.b = function(){};重寫

4, 分析執行階段,當執行到alert(num);時,認為num=10的想法是認為當前作用域沒有num變數。該想法是錯誤的,其實下面只要有宣告var num ;此時object.num = undefined,所以並不會向上去找父級作用域的num = 10;所以呢。。。就不是10了。

其實詞法分析並不難,只不過原來的時候掌握的一直不清晰所以造成了該處的疑惑,希望能夠幫到同樣有需求的同學。

參考文章:

js詞法作用域

通常來說,一段程式 中所用到的名字並不總是有效 可用的,而限定這個名字的可用性的 範圍就是這個名字的作用域.作用域的使用提高了程式邏輯的區域性性,增強程式的可靠性,減少名字衝突 考慮如下情況 var name chromium function init displayname init 彈出moz...

詞法作用域和動態作用域

作用域是指程式源 中定義變數的區域。它規定了如何查詢變數,也是就確定當前執行 對變數的訪問許可權。js 採用了詞法作用域 lexical scoping 也就是靜態作用域。js 採用的詞法作用域是靜態作用域,因此函式的作用域在函式定義的時候就決定了。與靜態作用域相對的是動態作用域,函式的作用域是在函...

js中的詞法作用域,this和塊級作用域

js中的詞法作用域,this和塊級作用域 箭頭函式的this會忽略物件,塊級作用域。func3 a undefined 以下來自 當我們將箭頭函式直接用於物件的方法時,this的指向就發生了變化 varobj console.log obj.getage uncaught typeerror can...