js 函數作用域, 塊級作用域和詞法作用域


函數作用域, 塊級作用域和詞法作用域

0  作用域:
    0.1 作用域是程序源代碼中定義變量的區域。
    0.2 作用域規定了如何查找變量,也就是確定當前執行代碼對變量的訪問權限。
    0.3 ECMAScript6之前只有全局作用域和函數作用域。
    0.4 JavaScript采用詞法作用域(lexical scoping),也就是靜態作用域。
    var scope = "global scope";
    function checkscope(){
        var scope = "local scope";
        function f(){
            return scope;
        }
        return f();
    }
    checkscope(); //local scope
    var scope = "global scope";
    function checkscope(){
        var scope = "local scope";
        function f(){
            return scope;
        }
        return f;
    }
    checkscope()();//local scope
1  變量作用域:全局變量和局部變量
    var a=1;                    //全局變量
    function B(){
        alert(a);
    }

    function B(){
        var c=1;                //局部變量
        alert(c);
    }
     
    function C(){
        d=1;                    //全局變量
        alert(d);
    }
    d;//1
2  閉包:就是能夠讀取其他函數內部變量的函數。由於在Javascript語言中,只有函數內部的子函數才能讀取局部變量,因此可以把閉包簡單理解成"定義在一個函數內部的函數"。所以,在本質上,閉包就是將函數內部和函數外部連接起來的一座橋梁。
    2.1 用途:以讀取函數內部的變量;讓這些變量的值始終保持在內存中。
            function f1(){
                var count=6;
                add=function(){
                    count+=1;
                }
                function f2(){
                    console.log(count);
                }
                return f2;
            }
            var f=f1();
            f();//6
            add();
            f();//7
        原因就在於f1是f2的父函數,而f2被賦給了一個全局變量,這導致f2始終在內存中,而f2的存在依賴於f1,因此f1也始終在內存中,不會在調用結束后,被垃圾回收機制(garbage collection)回收
    2.2 注意點:
         2.2.1 由於閉包會使得函數中的變量都被保存在內存中,內存消耗很大,所以不能濫用閉包,否則會造成網頁的性能問題,在IE中可能導致內存泄露。解決方法是,在退出函數之前,將不使用的局部變量全部刪除。
         2.2.2 閉包會在父函數外部,改變父函數內部變量的值。所以,如果你把父函數當作對象(object)使用,把閉包當作它的公用方法(Public Method),把內部變量當作它的私有屬性(private value),這時一定要小心,不要隨便改變父函數內部變量的值。
3  詞法作用域
    3.1 一般來說,在編程語言里我們常見的變量作用域就是詞法作用域與動態作用域(Dynamic Scope),絕大部分的編程語言都是使用的詞法作用域。詞法作用域注重的是所謂的Write-Time,即編程時的上下文,而動態作用域以及常見的this的用法,都是Run-Time,即運行時上下文。詞法作用域關注的是函數在何處被定義,而動態作用域關注的是函數在何處被調用。JavaScript是典型的詞法作用域的語言,即一個符號參照到語境中符號名字出現的地方,局部變量缺省有着詞法作用域。
        function foo() {
            console.log( a ); // 2 in Lexical Scope ,But 3 in Dynamic Scope
        }

        function bar() {
            var a = 3;
            foo();
        }

        var a = 2;

        bar();


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM