看下面的代码:
if (!("aa" in window)) {
alert('oh my god');
var aa = 1;
}
alert("aa" in window);
alert(aa);
回答以下问题:
会报错吗?会弹出几次?
第2个alert是true还是false?
第3个alert弹出什么?
为什么?
思考下,然后测试下,如果你回答正确,那么后面的文章就不用看了。
-----------------------------
在JS里定义变量太简单了,直接一个var ,甚至不用var都可以:
var a = 1;
这里a就是变量名,1就是变量值。唉,这个太基础了。看下面的代码:
var a;
alert(a);
以firefox测试,会弹出undefined,这个是大家很熟悉的一个字符串了,貌似表示变量未定义。但我觉得,我已经var了啊,这就是定义了嘛,只是没有附值而已。
我们来个真正的没有定义的:
alert(a);
没错,就是直接alert一个根本没有出现过的变量,这会如何?
firebug直接报错了:a is not defined.意思是a没有定义。这个结合前面的代码来看,让人困惑。这个没有定义和前面的未定义有什么不同呢?
其实前面的代码等价于这样的:
var a = undefined;
alert(a);
也就是说,当声明变量而不赋值时,JS会给变量传一个undefined值,注意,这是个“值”,说明a已经有值了,只是这个值就叫“未定义”。
而后面的直接alert,变量从没有出现过,也就是说这才是真正的未定义。
简单的说:JS中不存在没有值的变量,变量声明的时候就赋值了。
然后我们看下面的代码:
alert(a);
var a = 1;
这个代码会报错吗?因为在alert的时候变量a还没来得及出现呀。
但是这样居然没有报错,而是弹出了undefined值。表明变量a已经存在了,只是值却不是我们想要的,而是undefined。这又是个什么问题呢?
因为var 变量声明和函数声明一样,会提前,其实上面的代码是这样的:
var a;
alert(a);
a = 1;
这么一来就懂了。
所以,这个问题的关键在于:var 声明会提前到作用域顶端,但附值却不会———好纠结的设定,不知道为什么要这么搞。
现在放出文首问题的答案:
只会弹出两个alert,而if里面的alert不会执行,因为var声明的提前性,导致真正的代码是这个样子:
var aa;
if (!("aa" in window)) {
alert('oh my god');
aa = 1;
}
alert("aa" in window);
alert(aa);
虽然aa为空,但用‘aa’ in window判断时会为真,因为aa确实存在了,值是undefined。所以if代码不会执行。后面两个alert我就不说了。