javascript闭包及作用域

1.闭包

所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。

闭包的含义:闭包说白了就是函数的嵌套,内层的函数可以使用外层函数的所有变量,即使外层函数已经执行完毕(这点涉及JavaScript作用域链)。

 

示例一:

function checkClosure(){
    var str = 'rain-man';
    setTimeout(
        function(){ alert( str ); } //这是一个匿名函数
    , 2000);
}
checkClosure();

 

函数内部的一个变量能够在函数外面被引用时,我们就称创建了一个闭包
function inc(a) {
    var i = 0;
    return function() {
        return i;
    };
}
var num = inc();
alert(num());

  

2. Javascript的作用域

1.在Javascript预编译时,会把所有var变量创建,默认值为undefined
 
看这样一段代码:
   <script type="text/javascript">
        var a = "hello";
        b = "world";
       Test();
        function Test() {
            alert(a + " " + b);          // undefined world
            var a = "welcome";
            b = "china";
            alert(a + " " + b);         //  welcome china 
        }
        alert(a + " " + b);             //  hello china.
    </script>

a在预编译的过程中就已经被创建并且初始化为undefined,而b却只能在实际运行时按顺序去解释

2.js的运行顺序


如果一个文档流中包含多个script代码段(用script标签分隔的js代码或引入的js文件),它们的运行顺序是:
步骤1. 读入第一个代码段(js执行引擎并非一行一行地执行程序,而是一段一段地分析执行的)
步骤2. 做语法分析,有错则报语法错误(比如括号不匹配等),并跳转到步骤5
步骤3. 对var变量和function定义做“预解析”(永远不会报错的,因为只解析正确的声明)
步骤4. 执行代码段,有错则报错(比如变量未定义)
步骤5. 如果还有下一个代码段,则读入下一个代码段,重复步骤2
步骤6. 结束

3. 语法分析和“预解析”
(1)、从解释型语言的编译过程说起
众所周知,javascript是解释型语言,它不同于c#和java等编译型语言。

对于传统编译型语言来说,编译步骤分为:词法分析、语法分析、语义检查、代码优化和字节生成;

但对于解释型语言来说,通过词法分析和语法分析得到语法树后,就可以开始解释执行了。

原文地址:https://www.cnblogs.com/peng14/p/2668215.html