看到《js语言精髓与编程实践》中讲解的js语法中运算符的二义性之逗号的二义性,做些笔记

我们先来看看这两个例子:

	alert(eval('a=(1,2,3);'));//示例1
	alert(eval('a=1,2,3;'));//示例2

结果是两者都会弹出3,这种用法产生的混乱,是因为逗号“,”既可以是语法分隔符,又可以是运算符所导致的。在上面的示例1,示例2中,逗号都被作为”连续运算符“在使用。示例1中的括号是强制运算符,因此它的效果是运算如下表达式:

	(1,2,3)

并将结果赋值给变量a。由于该表达式是三个(直接量的)单值表达式连续运算,其结果值是最后一个表达式,亦即是数值3.而示例2因为没有括号来强制优先级,因此按默认优先级会先完成赋值运算,效果时“变量a赋值为1”,示例2在完成赋值运算“a=1”之后,还仍将继续指向连续运算,而最后一个表达式就是直接量3。下面来看示例3:

	a=(1,2,(3,4,5),6);//示例3

同样的,我们也可以知道示例3的结果是使变量a赋值为:

[1,2,5,6]

这是因为表达式“(3,4,5)”将会被先运算并返回结果值5,作为数组声明时的一个元素。示例3中要强调的是,逗号在这里分别有“数组声明时的语法分隔符”和“连续运算符”两种作用。但是如果像示例4:

	var a=1,2,3;//示例4

这样,逗号被解释成了语句var声明时用来分隔多个变量的语法分隔符,而不是连续运算符。而语句var要求用“,”号来分隔的是多个标识符,而数值2和数值3显然都不是合法的表只发,因此示例4的代码会在语法解释期就提示出错。存在同样混乱问题的,还有下面这个示例5的例子:

	//示例5.显示最后表达式的值"value:240"
	var i=100;
	alert((i+=20,i*=2,'value:'+i));

弹出“value:240”,因为在这个示例的alert()函数调用中,还存在一对括号,用来表示强制运算。因为alert()是函数,所以如果这样写:

	alert(i+=20,i*=2,'value:'+i);//示例6

	alert()函数会理解为三个参数传入而函数参数表的传值顺序是从左至右的那么示例6这行代码会被理解为

	alert(120,240,'value:240');

但alert()函数自身只会处理一个参数,因此最终显示的结果会是值“120”,而不是我们期望的240,但需要补充的是,这行代码执行完毕之后,变量i的值其实已经变成240了,为了让js理解这里的逗号“,”是连续运算符,而不是函数参数表的语法分隔符,我们在这里加入了一对强制(表达式)运算的括号,即是示例5,这样,由于外层的括号是函数调用符,因此将内部的

	(i+=20,i*=2,'value:'+i)

理解为一个参数,并且是一个需要求值的表达式。因此这里的括号就顺理成章地理解成了“强制运算符”,下面的代码:

	i+=20
	i*=2
	'value:'+i

也就被作为这个强制运算符的一个运算元:由“,”连接起来的一个表达式。直到饶了这样大的一个圈子,逗号才被合理地解释为“连续运算符”。