function mm(){ }
这种形式是声明一个函数,跟 var 一个变量的机制一样,脚本在解释执行之前会做预编译处理,而
var mm = function(){ }
这种形式是对一个变量赋值,虽然也做预编译,但仅仅只是给 mm 事先变量分配一个内存空间,而没有做初始化
请测试以下几段代码
代码一:
<script type="text/javascript">
window.alert(mm);
function mm(){
}
</script>
以上代码你会看到能 alert 出来 mm 的内容,但 alert 却是在 function 声明之前的,验证了脚本宿主在执行之前对脚本做了预编译处理
代码二:
<script type="text/javascript">
window.alert(mm);
var mm = 123;
</script>
以上代码你会看到 alert 出一个 undefined 来,说明脚本宿主在执行之前对脚本做了预编译:对 mm 分配内存空间但并不初始化它
代码三:
<script type="text/javascript">
window.alert(nn);
window.alert(aa);
if(true){
function mm(){ }
var aa = 1;
}else{
function nn(){ }
var aa = 2;
}
</script>
以上代码再次验证了预编译,并且说明预编译与条件无关。先弹出nn的函数定义,再弹出undefined。
Note: 解释一下Js变量的作用域
JavaScript的变量也是有作用域的,只是它非常的笼统,就分为全局变量和函数变量(局部变量)
在函数体外定义的变量(任何形式)和函数体内通过省略"var“定义的都为全局变量, 函数体内通过var定义的变量为局部变量。
Example:
<script type="text/javascript">
var x = 1; //x1
function check()
{
alert(x); // r1
var x = 1; //x2
alert(x); // r2
}
check();
</script>
Result: r1 弹出内容"undefined", r2 弹出内容 "1".
Reason Description:
函数体外定义的x是全局变量,在预编译过程中所有的x声明与函数声明处理,分配了存储单元,相当于做了简单的记录,但是并没有js的执行(比如:变量的初始化等)。
当执行时,会对第一个x(x1)初始化赋值,然后调用check()函数,进入check()内部,执行alert(x)语句,这是js解析器先在函数体内部寻找x,因为在预编译阶段已经记录了函数体内x(x2)的声明,所以编译器会取函数体内部定义的x(x2),但是x(x2)只有声明(值为"undefined"),所以alert出来的就是"undefined". 如果没有函数体内的x(x2)的定义语句,js解释器在函数体内找不到x的定义,就会往上一层次寻找,本例中就是到函数体外寻找x(全局变量)的定义,这时的x已经初始化过了,所以这个时候alert出来就是1了。