01-表达式和运算符
第5章 表达式和运算符
表达式是一种特殊的语句,它可以计算出一个值。表达式语句(结果产生一个值)和非表达式语句(不产生值)的区别至关重要,理解它们的差异能够帮助你用实用的方式组合编程语言中的元素。
大家可以认为非表达式语句是一条指令,而表达式语句是一个请求。想象如果第一天上班,领班走过来说:“你的工作是将部件A固定到法兰B(译者注:法兰是轴与轴之间相互连接的零件,用于管端之间的连接)上。”这是一个非表达式语句:领班没有让你上交装配后的零件,仅仅是命令你去做装配。如果领班说:“将部件A固定到法兰B上,然后交给我检查”,这就相当于一个表达式语句:你不仅仅接收到一个命令,而且执行完命令后要返回结果。大家可能会觉得这两种方法都会导致同一个结果:不论是把装配好的零件放回到生产线还是上交给领班检查,零件本身始终是存在的。在编程语言中也是类似的:非表达式语句通常会产生某种结果,但是只有表达式语句会对生成的结果做显式的转换。
因为表达式能解析成值,所以可以将它们与其他表达式组合在一起,进而将返回的结果再与其他表达式进行组合,以此类推。从另一方面讲,非表达式语句也有一些用处,但它们不能以同样的方式组合在一起。
因为表达式能解析成值,所以可以用它们来赋值。也就是说,可以将表达式的值赋给变量、常量或者属性。下面来考虑一种常见的运算表达式:乘法。乘法肯定是一个表达式:两个数字相乘,返回一个结果。来看两个非常简单的语句:
let x;
x = 3 * 5;
第一行是一个声明语句,声明了一个变量x。当然,也可以合并这两行,不过这么做会给当前的讨论造成困惑。有意思的是第二行:这一行中存在两个组合在一起的表达式。第一个表达式是 3``×``5 ,结果为 15 。然后赋值表达式将 15 赋给变量 x 。注意,赋值本身就是一个表达式,而表达式最终会解析成值。所以赋值表达式的值是什么呢?实践证明,赋值表达式的值就是所赋的值。所以,不仅是 x 被赋值为 15 ,而且整个表达式的值也是 15 。因为赋值本身也是一个能解析成值的表达式,可以把它赋给其他变量。来看下面这个例子(可能有点无聊)
let x, y;
y = x = 3 * 5;
注意,这里有两个变量,x和y,它们的值都是 15 。之所以可以这么做是因为乘法和赋值都是表达式。当JavaScript遇到这样的表达式的时候,必须先将它们分解,然后分别求值,就像这样:
let x, y;
y = x = 3 * 5; // 原始语句
y = x = 15; // 执行乘法表达式
y = 15; // 执行第一个赋值表达式; x 的值为 15,
// y 的值仍然是 undefined
15; // 执行第二个赋值表达式; y 的值为 15,
// 结果为15, 因为没有继续被使用,所以最终结果被丢弃
自然会有人会问:“avaScript怎么知道要按照那样的顺序去执行?”也就是说,它首先会恰当地执行 y = x 的赋值,此时y的值为 undefined ,然后对乘法求值,最后才赋值,而y仍然是 undefined , x 却变成 15 了。JavaScript对表达式求值的顺序叫作运算符优先级,这部分内容会在本章进行讲解。
大部分表达式,比如乘法和赋值,都是运算符表达式。也就是说,一个乘法表达式是由一个乘法运算符(*)及两个操作数(相乘的数字本身也是表达式)组成。
有两种非运算符表达式,它们是标识符表达式(变量名和常量名)和字面量表达式:变量和常量本身就是一个表达式,字面量也是。理解这一点后会明白表达式的本质:任何能够产生值的语句都是表达式,所以不难理解变量、常量以及字面量都是表达式。