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();

猜你喜欢

转载自www.cnblogs.com/shuajing/p/10805328.html