美文网首页
JavaScript的坑(二)

JavaScript的坑(二)

作者: zyfEve | 来源:发表于2016-10-12 14:49 被阅读30次

    上一篇文章:JavaScript的坑(一)有兴趣的可以看看哦!

    var a = 1;
    function foo() {
        if (!a) {
            var a = 2;
        }
        alert(a);
    };
    
    foo(); // 输出2,不是1!
    

    alert(a)在执行的时候,会去寻找变量a的位置,它从当前作用域开始向(或者说向外)一直查找到顶层作用域为止,若是找不到就报undefined。
    因为在alert(a)的同级作用域里,我们再次声明了本地变量a,所以它报2;所以我们可以把本地变量a的声明向下(或者说向内)移动,这样alert(a)就找不到它了。像下面那样:

    var a = 1;
    function foo() {
        if (!a) {
            (function() {        // 这是 IIFE,它会创建一个新的函数作用域
                var a = 2;       // 并且该作用域在 foo() 的内部,所以 alert 访问不到
            }());               // 不过这个作用域可以访问上层作用域哦,这就叫:“闭包”
        };
        alert(a);
    };
    foo();//输出1
    

    记住:JavaScript 只有函数作用域!

    function test() {
        foo();
        //函数声明
        function foo() {
            alert("我是会出现的啦……");
        }
    }
    test();//输出我是会出现的啦……
    
    function test() {
        foo();
        //函数表达式
        var foo = function() {
            alert("我不会出现的哦……");
        }
    }
    test();//报错:Uncaught TypeError: foo is not a function
    

    在第一个例子里,函数 foo 是一个声明,既然是声明就会被提升。函数声明会连通命名和函数体一起被提升至作用域顶部。
    在第二个例子里,被提升的仅仅是变量名foo,至于它的定义依然停留在原处。因此在执行foo()之前,作用域只知道foo的命名,不知道它到底是什么,所以执行会报错(通常会是:undefined is not a function)。这叫做函数表达式(Function Expression)

    函数表达式只有命名会被提升,定义的函数体则不会。
    函数声明会在js解析器解析时候率先解析,保证其他代码执行之前,函数可用。而函数表达式必须要等到代码解析器解析到他所在代码行,才会被解释执行。

    相关文章

      网友评论

          本文标题:JavaScript的坑(二)

          本文链接:https://www.haomeiwen.com/subject/vjsiyttx.html