很多JS的初学者都对作用域没有很好的理解,会有一些理解偏差,甚至是错误,比如下面就是笔者错过的一道题:
var x = 5; function a(x){ if(x > 0){ x++; } console.log(x); } a(1); console.log(x);
在上面程序中第二个console.log(x)的输出结果是?
a:2 b:3 c:5 d:6
你的选择是什么呢?笔者曾经傻傻的选择了d,习惯了C/C++语言,想当然的认为变量x=5>0,x++结果是
6,这充分表现出笔者当时对JS中函数还有作用域的理解错误;正确答案是c,我们来分析一下:
在最上面的x=5处于顶层作用域,它的作用域是最大的,函数a()在没有调用时是没有输出结果的,这时的
console.log只是摆设,只有在下面a(1)调用a()参数x取1后console.log()才输出结果2,然而最后一行的console.log()输出的结果是5,这就是作用域的原因了,在函数中x=5由于x的重名被子作用域覆盖在函数a()未被调用时没有被赋值,应该是预定义的undefined,而不是5,但函数中x的作用域只在函数中,并没有改变
父作用域中变量x,故输出结果依然是5。
还有一个问题笔者曾经疑惑过,如下:
for(var i=0;i<20;i++) { if(i%2==0) { i++; } } console.log(i);
循环体条件判断if内的i++会影响上面更新表达式中的i++吗?通过测试输出结果证明不会影响,由于循环体
实际上是需要执行的独立代码块,而for()中的初始化表达式,条件表达式和更新表达式是循环条件,不会受
循环体中变量影响。