这期的测试内容非常的有趣,下面慢慢的道来。题目是

var price = 100;
function doSomething() {
    var doublePrice = price * 2;
    var price = 200;
    var halfPrice = price / 2;

    alert(doublePrice);
    alert(halfPrice);
}
doSomething();

请问两个 alert 弹出值分别是多少?

不要轻易相信自己的判断,建议将这段代码放到浏览器运行下,相信结果会感到非常的意外 -- 答案是 doublePrice 是 NaN、halfPrice 是 100 。

会很奇怪为什么会是这样的结果,小虎 同学的解释为,「第一行 price 被下面的 var price 重新定义,所以它是未定义的」。代码可以认为如下:

var price = 100;
function doSomething() {
    var price;
    var doublePrice = price * 2;
    price = 200;
    var halfPrice = price / 2;

    alert(doublePrice);
    alert(halfPrice);
}
doSomething();

理解这个问题,要理解 Javascript 的作用域。已经存在一个全局变量 price, 按照其他语言的情况,doublePrice = 全局 price 变量 2;而事实上,Javascript 会先检查函数内部变量作用域,上述的代码中 doSomething() 内部也有个同名的 price 变量。于是 doublePrice = 内部 price 变量 2 (小马总结)。

某个变量如果未声明(没有 var)而直接使用,那在它的第一次被调用的作用域里(子作用域里不算)。只要有一个地方对其进行了声明,那它就属于该作用域,否则它的作用域会是上一级(直上到顶层) -- form 圆心 。

因此,需要注意 Javascript 这个特性。首先,得意识到「全局变量是魔鬼,大型的项目随着发展,(如果考虑不周全)变量的命名很有可能和函数中的临时变量同名」,建议适度使用闭包避免此问题。

其次在函数中,尽量把要用到的变量名写在函数的顶部。「这点也需要注意下的就是,虽然 Javascript 没有块作用域,但为了清晰起见,该在块里定义的变量,个人觉得还是在块里定义比较好」 -- form 玉伯 。

最后,再用 玉伯 的一道题结束本文:

 看看下面的代码,运行结果是什么?

function test() {
    alert(」test function 1″);
}

test();

function test() {
    alert(」test function 2″);
}

详细信息请 参见这里

--EOF--