1.闭包
所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。
闭包的含义:闭包说白了就是函数的嵌套,内层的函数可以使用外层函数的所有变量,即使外层函数已经执行完毕(这点涉及JavaScript作用域链)。
示例一:
function checkClosure(){
var str = 'rain-man';
setTimeout(
function(){ alert( str ); } //这是一个匿名函数
, 2000);
}
checkClosure();
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等编译型语言。
对于传统编译型语言来说,编译步骤分为:词法分析、语法分析、语义检查、代码优化和字节生成;
但对于解释型语言来说,通过词法分析和语法分析得到语法树后,就可以开始解释执行了。