对于从未声明过的对象,如果尝试给它赋值,会隐式的将它声明为全局对象。比如:
(function() {
s = 'abc';
})();
alert(s); //会弹出 abc
如果尝试读一个未声明的对象,JS会报错。比如:
alert(a); //不会弹出对话框,会报错
这个结论是犀牛书中所写。但是有意思的是,在IE里,如果尝试读一个未声明的对象,并不会报错,当然也不会继续执行JS。这点其实挺要命,不执行也不告诉你为什么。
但这个结论是铁律,所以如下的写法是经常容易犯的错误:
if(!a) {
//do sth. ...
}
这样写有时候的初衷是:如果变量a不存在,就执行里面的语句。但如果a未定义,在Firefox中会报错;在IE里不会报错,但也不会执行以后的所有语句。
所以该如何探测一个变量是否被定义呢?一个巧妙的办法是:
if(!window.a) {
//do sth. ...
}
这个方法其实很奇妙,因为读一个未声明的变量,会报错;但读一个未声明的属性,就不会报错。天晓得JS为啥规定这样奇怪的语法。
但是这样的方法只适用与全局变量。若是某个函数里的局部变量,还是用typeof去判断吧:
if(typeof a == 'undefined') {
//do sth. ...
}
所以,结论就是,养成习惯,不要在变量未定义之前使用它。
接下来再看一个例子:
var a = "I'm out";
(function() {
alert(a);
var a = "I'm in";
})();
好,提问,运行这段代码,会弹出什么文字?
回答一:弹出“I’m out”。错。JS没有块级作用域,无论var语句在何处,在整个函数体内它都是有定义的。
回答二:弹出“I’m in”。错。请再重新看上面那句话,它只是在整个函数体内有定义,但只有在被赋值之后才会有值。
正确答案是:“undefined”。是不是很晕?自己试试看吧。
总之,再重复一遍之前的结论:不要在变量未定义之前使用它。
最后介绍一个我也搞不明白的问题:
在HTML文档里写上这段代码:
<script type="text/javascript"> window['a'] = 'Hi'; </script> <script type="text/javascript" src="out.js"></script> <script type="text/javascript"> alert(a); </script>
然后在out.js里写上这句:
if(false) {
var a = 'Hello';
}
然后用FF和IE6分别运行,看看你得到什么。
在FF里会弹出“Hi”,但是在IE6中,会得到“undefined”。
很神奇吧?按语法,无论如何,a都不可能是undefined。但是IE6里就会。
如果把两个语句都写在同一个文件里,就不会有这个情况。
如果把out.js里改成window.a,或者把前一个改成var a,也不会有这个情况。
如果把out.js里的var a移到if语句之外,或是把if的条件改为true,也不会有这个情况。
这个bug其实危害性很大。所以呢,只能给自己定一个好习惯,那就是不要在条件语句中声明变量,虽然这么做,语法上并不禁止。
大仙: 2009-1-10 11:25 am
刚学习javascript。
1、不要在变量未定义之前使用它。
2、不要在条件语句中声明变量
Lion: 2009-1-10 3:42 pm
检查有没有定义,标准的方法是
if (typeof(value_name) != “undefined”)
小麦: 2009-1-11 12:13 am
呃,怎么说呢,typeof没法区分出未定义和已经定义未赋值。不过这个方法是正确的,我一时忘记了,呵呵。已经在文中补上了。
z.Yleo77: 2009-1-14 7:28 pm
我理解的未定义的变量报错,但未声明的属性不报错,是因为js默认他为undefined。
Greco: 2009-2-3 9:36 am
你的blog设计的也一般
1. 分类、个人信息、评论都在下面
每次要看一个分类都要拖到最下面,麻烦
2. 页面右面那个页签,我一开始还以为只是装饰用的标尺
后来才发现,原来是页签
Kim Wang: 2009-2-4 1:52 pm
文章最后提到的alert(a); //undefined的原因是,javascript预编译所致~
if(false) {
var a = ‘Hello’;
}
javascript在执行代码会定义所有var声明的变量(但不会赋值,此时值是undefined),在运行时才会给这个变量赋值…
若改成
if(true) {
var a = ‘Hello’;
}
alert(a)://会弹出Hello
hax: 2009-3-14 1:08 pm
为什么评论写不上去?
hax: 2009-3-14 1:09 pm
是不是因为带有标签?
hax: 2009-3-14 1:10 pm
再测试一下:
<script>
hax: 2009-3-16 2:52 am
对于未定义变量,IE会报错的,你用try catch就可以抓到了。
属性不报错是合理的,因为它是动态语言。
最后那个例子,关键不在于block块,因为所有的var声明都会被提前处置。IE的特殊在于它的全局变量有DID(人格分裂症) ^_^
请看本篇blog:http://hax.javaeye.com/blog/349569
GreatGhoul: 2009-10-29 10:04 pm
说实话,在看这篇文章之间,我从来没有见过这种错误.