javascript 詞法做用域

詞法做用域

定義在詞法階段的做用域,開始時,編譯器作語法分析的時候,確認js裏各個詞法所在的做用域。

js裏只有全局做用域和函數做用域,這裏簡單介紹下js的做用域。異步

js做用域

看下面代碼:函數

var a = 1;
        var b = 0;

        function foo() {
            var a = 2;
            console.log(a); //2
            console.log(b); //0
        }
        foo();
        console.log(a); //1

一、在foo函數裏,在console.log(a),對a進行RHS查詢,發如今當前做用域存在變量a,若是foo裏沒有a就往上一層(全局)去查找
二、在foo函數裏,在console.log(b),對b進行RHS查詢,發如今當前做用域不存在變量b,而後往上一層(全局)去查找b,發現存在變量b,獲取b的值。code

在詞法分析階段,會確認在全局做用域裏有a,b這兩個變量,函數foo做用域裏有a這個變量對象

可是,有些方法能夠欺騙或者動態生成做用域。作用域

例如:eval、setTimeout、with等字符串

eval

eval函數能夠理解爲在當前做用域插入一段代碼。編譯器

以下:it

var b = 2;

        function foo() {

            eval('var b=1')

            console.log(b); //1
        }

        foo();
        console.log(b); //2

在開始的詞法分析中,foo函數做用域並不存在變量b,然而在引擎執行代碼的時候,到eval函數執行,就強行在foo函數做用域中插入變量bio

setTimeoutconsole

定時器函數是一個異步函數,第一個參數中字符串的執行做用域是全局做用域,相似上面動態插入變量。

var b = 1;

        function foo() {

            setTimeout('var b =2', 0);
            setTimeout('console.log(b)', 0); //2
        }
        foo();
        console.log(b); //1

with

擴展一個語句的做用域鏈。

在一個對像是擴展屬性,若是屬性存在就修改屬性值,若是不存在就掛載在全局對象上,相似於在函數裏不用var聲明的變量都掛在window對象上。

相關文章
相關標籤/搜索