参考:
https://www.web-tinker.com/article/20015.html
1 | if(1){ |
看到这个代码,你会觉得它只有一个if语句,和一个判断为真时调用的函数。但是,事实上不止这些,if语句的部分仅仅是if(1)这个而已,而判断为真之后调用的函数也只是alert(0);这个而已。就这样,大括号完全被忽略了。人们通常会觉得,那个大括号是术语if语句的东西,其实不然。无论是if语句还是大括号,他们都是可以单独存在的。1
2
3
4
5
6//if语句
if(1);//用分号结束的话,条件为真就执行一个空语句。
//大括号,可以作为一个独立的语句
{
alert(0);
};
它们完全可以作为独立的两个语句。if语句的作用,是判断条件是否成立,成立则执行紧接着的那个语句。而大括号在这里就是代码块,或者说匿名代码块。它是一个独立的语句,而它的作用是把许多个语句变成一个语句。比如有时候,if语句判断为真以后要做很多个动作,那么就会需要很多语句,而if本身判断为真以后只会执行紧接着的那个语句,这时候用大括号,把需要执行的一堆语句放在一个大括号中,变成代码块,这样就把一堆语句变成了一个语句。虽然if和大括号可以独立称为语句,但是它们写在一起的时候实际上是一个语句,这是因为if本身的功能是判断条件后直接后面的语句,所以“后面的语句”就变成了if的一部分,按照语句来划分就把“后面的语句”归入if语句中了。
通常,我们用的都是匿名代码块,但是还有命名代码块可以用。
1 | if(1)a:{ |
看这个代码,我们对if后面执行的代码快命名为a,在代码块内部,执行完第一个alert之后就强制结束这个代码块,那么后面的alert(1)就不会被执行到。也许在书本上找不到“命名代码块”这个东西,但是你可以结合label语句和break语句这这两个东西好好看看就会明白。label语句的作用是给语句命名,这里我们给代码块命名,所以就成了命名代码块。break语句通常是跳出循环,但是添加个操作数就可以跳出制定语句。这里的制定,这是说用label命名的语句。在这个例子中if语句其实可以去掉的,放着只是为了让break感觉上是从一个语句中跳出的。
命名代码块这玩意儿有什么用呢?比如表单验证之后需要执行很复杂的语句时就适合用匿名代码块
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22<form name="f">
<input name="t1" /><br/>
<input name="t2" /><br/>
<input name="t3" /><br/>
<input name="t4" /><br/>
<input type="submit" />
</form>
<script>
var f=document.forms.f;
f.onsubmit=function(){
chk:{
if(f.t1.value=="")break chk;
if(f.t2.value=="")break chk;
if(f.t3.value=="")break chk;
if(f.t4.value=="")break chk;
alert("验证通过!");
return true;
};
alert("验证失败");
return false;
};
</script>
当然也可以使用一个变量作为验证成功与否的标识符,最后再判断那个变量;或者还可以用函数去做,验证失败时直接return掉;方法是很多的,但是这只是方法之一。懂得它的用法就可以了,也许以后你会遇上更适合用这个方法解决的问题。
最后,来说一说歧义句。1
{id:0};//这是个啥?
一眼看过去,像是一个对象声明吧?但是又没有赋值语句,说是标准JSON又缺对双引号。其实,这玩意儿是1
2
3{
id:0
};
一个大括号语句,里面把0这个没用没有动作的语句命名为id而已。1
2
3
4
5
6//{id:{name:"次碳酸钴"}};
{
id:{
name:"次碳酸钴"
}
};
这个也一样,这就是歧义句。如果想验证{id:0}到底是个啥?可以这样,1
alert(eval("{id:0}"));
这个代码输出的是0而不是object,所以显然这个大括号被解析为了代码块。如果想要让他输出object呢?很简单,让大括号做一个代码块不能做的操作,解析器就可以排除它是代码块的可能性了。1
alert(eval("({id:0})"));
只有这样,浏览器才能明白这玩儿而是一个object而不是代码块。这个歧义问题,可谓是JavaScript的一个BUG,自然语言有歧义就算了,编程语言怎么可以有歧义呢?所以后来标准JSON就被规定为所有键名必须加双引号,以区别开代码块和对象定义语句。