JavaScript高级程序设计:29 运算符

  位运算NOT由否定号(~)表示,它是ECMAScript中为数不多的与二进制算术有关的运算符之一。位运算NOT是三步的处理过程:

  位运算NOT实质上是对数字求负,然后减1,因此25变为-26。用下面的方法也可以得到同样的效果:

  位运算AND由和号(&)表示,直接对数字的二进制形式进行运算。它把每个数字中的数位对齐,然后用下面的规则对同一位置上的两个数位进行AND运算:

  可以看到,在25和3中,只有一个数位(位0)存放的都是1,因此,其他数位生成的都是0,所以结果为1。

  位运算OR由符号()表示,也是直接对数字的二进制形式进行运算。在计算每个位时,OR采用下列规则:

  可以看到,在两个数字中,共有4个数位存放的是1,这些数位被传递给结果。二进制代码11011等于27。

  位运算XOR由符号(^)表示,当然,也是直接对二进制形式进行运算。XOR不同于OR,当只有一个数位存放的是1时,它才返回1。真值表如下:

  可以看到,两个数字中共有4个数位存放的是1,它们被传递给结果。二进制代码11010等于26。

  左移运算由两个小于号表示()。它把数字中的所有数位向左移动指定的数量。例如,把数字2(等于二进制中的10)左移5位,结果为64(等于二进制中的1000000):

  注意,在左移数位时,数字右边多出5个空位。左移运算用0填充这些空位,使结果为完整的32位数字(如图2-6所示)。

  注意,左移操作保留数字的符号位。例如,如果把-2左移5位,得到的是-64,而不是64。“符号仍然存储在第32位中吗?”是的,不过这在ECMAScript后台进行,开发者不能直接访问第32个数位。即使输出二进制字符串形式的负数,显示的也是负号形式(例如,-2将显示为-10,而不是10)。

  有符号右移运算符由两个大于号()表示,它将把32位数字中的所有数位整体右移,同时保留该数的符号(正号或负号)。有符号右移运算恰好与左移运算相反。例如,把64右移5位,将变为2:

  同样,移动数位后会造成空位。这次,空位位于数字的左侧,但位于符号位之后(如图2-7所示)。ECMAScript用符号位的值填充这些空位,创建完整的数字。

  无符号右移由三个大于号()表示,它将把无符号32位数中的所有数位整体右移。对于正数,无符号右移运算的结果与有符号右移运算一样。用有符号右移运算中的例子,把64右移5位,将变为2:

  对于负数,情况就不同了。无符号右移运算用0填充所有空位。对于正数,这与有符号右移运算的操作完全一样,而负数则被作为正数来处理。由于无符号右移运算的结果是一个32位的正数,所以负数的无符号右移运算得到的总是一个非常大的数字。例如,如果把-64右移5位,将得到134217726。如果得到这种结果的呢?

  要实现这一点,需要把这个数字转换成无符号的等价形式(尽管该数字本身还是有符号的),可以通过以下代码获得这种形式:

  然后,用Number类型的toString()方法获取它的真正的位表示,采用的基为2:

  这将生成00,即有符号整数-64的二进制补码表示,不过它等于无符号整数4294967232。出于这种原因,使用无符号右移运算符要小心。

  Boolean运算符与等式运算符同等重要,是它们使得程序设计语言得以正常运行。如果不能测试两个值之间的关系,那么像if...else和循环这样的语句就没用了。Boolean运算符有三种,即NOT、AND和OR。

  在ECMAScript中,逻辑NOT运算符与C和Java中的逻辑NOT运算符相同,都由感叹号(!)表示。与逻辑OR和逻辑AND运算符不同的是,逻辑NOT运算符返回的一定是Boolean值。逻辑NOT运算符的行为如下:

  在这个例子中,Boolean变量(bFound)用于记录检索是否成功。找到问题中的数据项时,bFound将被设置为true,!bFound将等于false,意味着运行将跳出while循环。

  判断ECMAScript变量的Boolean值时,也可以使用逻辑NOT运算符。这样做需要在一行代码中使用两个逻辑NOT运算符。无论运算数是什么类型的,第一个NOT运算符返回Boolean值。第二个NOT将对该Boolean值求负,从而给出变量真正的Boolean值。

  逻辑AND运算的运算数可以是任何类型的,不止是Boolean值。如果某个运算数不是原始的Boolean型值,逻辑AND运算并不一定返回Boolean值:

  与Java中的逻辑AND运算相似,ECMAScript中的逻辑AND运算也是简便运算,即如果第一个运算数决定了结果,就不再计算第二个运算数。对于逻辑AND运算来说,如果第一个运算数是false,那么无论第二个运算数的值是什么,结果都不可能等于true。考虑下面的例子:

  这段代码在进行逻辑AND运算时将引发错误,因为变量bUnknown是未定义的。变量bTrue的值为true,因此逻辑AND运算将继续计算变量bUnknown。这样做就会引发错误,因为bUnknown的值是undefined,不能用于逻辑AND运算。如果修改这个例子,把第一个运算数设为false,那么就不会发生错误:

  在这段代码中,脚本将输出逻辑AND运算返回的值,即字符串false。即使变量bUnknown的值为undefined,它也不会被计算,因为第一个运算数的值是false。在使用逻辑AND运算符时,必须记住它的这种简便计算特性。

  ECMAScript中的逻辑OR运算符与Java中的相同,都由双竖线()表示:

  与逻辑AND运算符相似,如果某个运算数不是Boolean值,逻辑OR运算并不一定返回Boolean值:

  与逻辑AND运算符一样,逻辑OR运算也是简便运算。对于逻辑OR运算符来说,如果第一个运算数值为true,就不再计算第二个运算数。例如:

  与前面的例子相同,变量bUnknown是未定义的。不过,由于变量bTrue的值为true,bUnknown不会被计算,因此输出的是true。如果把bTrue的值改为false,将发生错误:

相关阅读