都知道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,分析形參: 此處無形參則不進行操作;當有形參時:
functiona (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...