表达式和运算符

 表达式是运算符和操作数(operand)的集合,或者是常量。

 通常用以下格式书写。

    表达式;

 像这样在表达式的后面加上分号(;)的话,该表达式会被当场求值( = 执行 ),而产生的结果会被丢弃。


例:
    a = b;
    // 由于 = 运算符的作用,b变量 的值被代入到 a变量 中

    func();
    // 由于 ( ) 运算符的作用,func 作为函数被调用,函数的返回值被舍弃

    1 + 3;
    // 由于 + 运算符的作用,1 和 3 被求和,其结果被舍弃(实际上
    // 因为这个表达式没有意义,它不会被执行)

真(true) 和 假(false)

 有些运算符用于对真和假 (逻辑值) 进行处理。运算结果为 0 是代表 假(false) ,非0 是代表 真(true) 。
 对字符串判断真假的时候,空字符串为 假、字符串非空的时候会被尝试转换为数值。如果转换成功就以转换结果的数值来判断真假,转换不成功则认定为 假。

运算符

 下面以优先级由低到高的顺序对各个运算符以下进行说明。

if 运算符

 条件运算符 if 会对其右侧的表达式求值,如果结果为 真 ,就会对左侧的表达式求值。

例:
    a=b if b!=0; // 如果 b 不为 0 则将 b 的值代入 a 


 该运算符并不返回运算结果。

顺序运算符

 顺序运算符 , (逗号) 会先对左侧的表达式求值,然后对右侧的表达式求值。除此以外什么都不做。右侧的表达式的结果会作为该运算符的执行结果。连续出现多个逗号的时候,会从左侧开始依次求值。

例:
    c = (a=1, b=2); // 对 a=1, b=2 这两个表达式进行求值,后面的表达式的结果 2 会被带入 变量 c 中
    a=1, b=2, c=3; // 按照 a=1, b=2, c=3 的顺序依次求值

赋值运算符

 下面的这些就是赋值运算符。

= <-> &= |= ^= -= += %= /= \= *= ||= &&= >>= <<= >>>=
 其中, = 运算符是单纯的赋值运算符,其作用是,先对右侧的表达式求值,然后将求得的结果代入左边的变量。以右侧的表达式的值作为该运算符的运算结果。

例:
    a = 0;  // 将 0 代入 变量 a 
    a = b = c = 0; // 将 0 依次代入变量 c , b, a 


 <-> 运算符用来进行值的交换。首先对左侧的表达式求值,然后对右侧的表达式求值。在那之后,将右侧表达式的值代入左侧的变量,左侧表达式的值代入右侧的变量。该运算符不返回结果。
 就目前来讲,为了对运算符左侧和右侧的表达式分别求值和代入,两侧的表达式发生了重复求值的现象。以后这个方法可能会改变,所以请不要设计利用这一特征的算法。

 除此之外的运算符都属于 运算符= 的形式,A 运算符= B 的写法相当于 A = A 运算符 B 。A 运算符 B 的结果就会作该运算符(运算符=)的结果。

条件运算符

 条件运算符 ? : 是一个三目运算符。写成 A ? B : C 的形式的话,会先对 A表达式 求值。结果为真的时候会对 B表达式 求值,忽略 C表达式。结果为假的时候会对 C表达式 求值,忽略 B表达式。B表达式 和 C表达式 中被求值的那个表达式的值会作为该运算符的结果。

 条件运算符可以作为左值使用。

例:
    a = b==0 ? c : b; // 如果 b 等于 0 那么 将 c 代入 a ,如果 b 不等于 0 则将 b 代入 a 
    b==0 ? (a=c) : (a=b); // 和上面的表达式具有相同的意义
    (a ? b : c ) = d; // 如果 a 为真,则将 d 代入 b ,如果a为假的话,则将 d 代入 c (作为左值使用的例子)

逻辑 或(OR) 运算符

 逻辑或运算符 || 会先对左侧的表达式求值,若结果为真,则忽略右侧的表达式,以“真”作为该运算符的结果。如果左侧表达式的结果为假,则对右侧的表达式进行求值,其结果(真或者假)作为该运算符的结果。

逻辑 与(AND) 运算符

 逻辑与运算符 && 会先对左侧的表达式求值,如果结果为假,则忽略右侧的表达式,以“假”作为该运算符的结果。如果左侧的表达式的结果为真,则对右侧的表达式进行求值,其结果(真或者假)作为该运算符的结果。

按位 或(OR) 运算符

 按位或运算符 | 用于对每个 字位(bit) 进行逻辑或运算。先对左右两侧的表达式分别进行求值,将两个结果作为整数,按位逐个进行或运算,其结果作为该运算符的结果。(译者注:一个字节(byte)为8位,即包含8个字位(bit))

按位 异或(XOR) 运算符

 按位异或运算符 ^ 用于对每个 字位(bit) 进行逻辑异或运算。先对左右两侧的表达式分别进行求值,将两个结果作为整数,按位逐个进行异或运算,其结果作为该运算符的结果。

按位 与(AND) 运算符

 按位与运算符 & 用于对每个 字位(bit) 进行逻辑与运算。先对左右两侧的表达式分别进行求值,将两个结果作为整数,按位逐个进行与运算,其结果作为该运算符的结果。

相等判断运算符

 == != === !==都属于相等判断运算符这一类。

== 运算符
== 运算符会先对左侧表达式求值,然后对右侧表达式求值。如果两个表达式的结果一致则该运算符的结果为真,不一致则该运算符的结果为假。两侧表达式的结果的数据类型如果不相同,则会进行适当的转换后再进行比较。例如,-1 == '-1' 结果为真。
!= 运算符
!= 运算符就是把 == 运算符的结果进行真假互换。
=== 运算符
=== 运算符被称为 类型识别比较运算符,它与 == 运算符类似,区别在于它不会进行数据类型自动转换,数据类型不同即被判断为假。
!== 运算符
!== 运算符就是把 === 运算符的结果进行真假互换。

比较运算符

 < > <= >= 都属于比较运算符这一类。

< 运算符
< 运算符会先对左侧表达式求值,然后对右侧表达式求值。如果左侧表达式的值小于右侧表达式的值,则运算符的结果为真,否则运算符的结果为假。
> 运算符
> 运算符会先对左侧表达式求值,然后对右侧表达式求值。如果右侧表达式的值小于左侧表达式的值,则运算符的结果为真,否则运算符的结果为假。
<= 运算符
<= 运算符会先对左侧表达式求值,然后对右侧表达式求值。如果左侧表达式的值小于或等于右侧表达式的值,则运算符的结果为真,否则运算符的结果为假。
>= 运算符
>= 运算符会先对左侧表达式求值,然后对右侧表达式求值。如果右侧表达式的值小于或等于左侧表达式的值,则运算符的结果为真,否则运算符的结果为假。

 比较的双方都是字符串的时候,会按照宽字符的编码的顺序(通常是UNICODE)来进行比较。

按位 移位(shift) 运算符

 >> << >>>都属于按位移位运算符这一类。

>> 运算符
>> 运算符会先对左侧表达式求值,然后对右侧表达式求值。将左侧表达式的结果作为整数,依照右侧表达式的结果所决定的次数进行向右的带符号位移,位移后的值作为该运算符的结果。
<< 运算符
<< 运算符会先对左侧表达式求值,然后对右侧表达式求值。将左侧表达式的结果作为整数,依照右侧表达式的结果所决定的次数进行向左位移,位移后的值作为该运算符的结果。
>>> 运算符
>>> 运算符和>>运算符类似,区别在于它将左侧表达式的值作为无符号整数来进行处理。

加减运算符

 + - 分别为加法运算符和减法运算符。

+ 运算符
+ 运算符会先对左侧表达式求值,然后对右侧表达式求值。如果两侧的结果都是数值,则将两边的结果相加,相加的结果作为该运算符的结果。如果某一侧,或者两侧的结果是字符串的时候,则两侧的结果都会作为字符串进行处理(其中数值或对象类型的数据如果能转换成字符串的话,会进行转换),将右侧的结果字符串连接到左侧的结果字符串的后面,作为该运算符的结果。
- 运算符
- 运算符会先对左侧表达式求值,然后对右侧表达式求值。把两侧的结果作为数值,从左侧的值中减去右侧的值,其结果作为该运算符的结果。

乘除取余运算符

 % / \ * 分别为取余、除法、整除和乘法运算符。

% 运算符
% 运算符会先对左侧表达式求值,然后对右侧表达式求值。之后,左侧的值除以右侧的值,所得的余数作为该运算符的结果。两侧表达式的值都作为整数来处理,结果也为整数。
/ 运算符
/ 运算符会先对左侧表达式求值,然后对右侧表达式求值。之后,左侧的值除以右侧的值,其结果作为该运算符的结果。结果为实数。
\ 运算符
\ 运算符会像 / 那样进行除法运算,只不过结果为整数。
* 运算符
* 运算符会先对左侧表达式求值,然后对右侧表达式求值。之后,左右两侧的值相乘作为该运算符的结果。结果为实数。

普通的单目运算符

 下面的运算符都是单目运算符 ( instanceof 除外 )。

! 运算符
前置的 ! 运算符是逻辑 非(NOT) 运算符。将右侧的表达式的结果进行真假调换,作为该运算符的结果。
~ 运算符
~ 运算符是按位取反运算符。将右侧表达式的结果作为整数,逐位取反 ( 1→0、0→1 ) 将取反后的值作为该运算符的结果。
-- 运算符
前置的 -- 运算符是前置递减运算符。将右侧表达式的值减1,减1之后的值作为该运算符的结果。
++ 运算符
前置的 ++ 运算符是前置递增运算符。将右侧表达式的值加1,加1之后的值作为该运算符的结果。
new 运算符
new 运算符右面的函数调用表达式并不会被作为函数调用,而是用来创建对象。
invalidate 运算符
invalidate 运算符会将右侧表达式的结果对象无效化。
isvalid 运算符
isvalid 运算符会先对右侧或者左侧的的表达式求值,如果得到的结果的对象是有效的,则该运算符的结果为真,如果是无效的,则该运算符的结果为假。该运算符放到操作数的前面或后面具有相同的效果。
delete 运算符
delete 运算符会将写在右侧的对象的成员或者全局变量删除。删除成功则返回 true、失败则返回 false 。(译者注:该运算符在删除对象成员或全局变量时,不会把对象成员或全局变量所指向的对象也删除掉。如果环境中还存在其他对那个对象的引用则那个对象将被保留。)
typeof 运算符
typeof 运算符会对右侧的表达式进行求值,随着结果的数据类型不同,会返回如下的字符串:void:"void"、整数:"Integer"、实数:"Real"、对象:"Object"、字符串:"String"、字节串:"Octet" 。但是,如果指定了某对象的成员,但是这个对象却是不存在的,就会返回 "undefined" 。
# 运算符
# 运算符会对右侧的表达式进行求值,将结果字符串的第一个字符的编码作为该运算符的结果。
$ 运算符
$ 运算符会对右侧的表达式进行求值,将结果作为字符编码,而把该字符编码对应的那个字符作为该运算符的结果。
+ 运算符
单目的 + 运算符会先对右侧的表达式进行求值。如果右侧的结果是实数或整数就什么都不做,否则就会尝试将其变换为实数或整数,最后的结果作为该运算符的结果。将字符转换为数值并且转换失败的时候并不会产生异常,而是返回0。如果右侧表达式的运算结果中有“包含小数点”这类实数特征的话,会尝试转换成实数,否则尝试转换成整数,如果是以0x、0b或0开头的字符串的话,分别按照16进制数、2进制数或8进制数来解析。
- 运算符
单目的 - 运算符会对右侧的表达式进行求值,将结果作为数值,将正负号取反之后作为该运算符的结果。
& 运算符
单目的 & 运算符可以把 对某对象的属性成员的操作(读或写) 在不导致属性中的 属性控制器(getter和setter) 被执行的情况下,转换为对该属性对象本身的操作。例如,propobj = &obj.prop; 这样写的话,obj 的成员属性 prop 的读写处理函数不会被执行,指向属性成员 prop 的属性对象本身的引用会被代入到 propobj 变量中。如果该运算符的右侧不是对属性的操作的话,该运算符的行为是不确定的。
* 运算符
单目的 * 运算符会导致该运算符右侧的属性对象的 读写处理函数 被执行。这个运算符的右侧必须是代表属性对象的表达式。例如,*propobj = 1; 这样写的话,作为属性对象的 propobj 的 setter 方法被调用,1 被代入。
instanceof 运算符
instanceof 运算符会先对左侧表达式求值,然后对右侧表达式求值。如果右侧的字符串是某个类的名字,而左侧是这个类的实例,则该运算符返回 true ,否则返回 false 。

函数调用,括号类,后置的递增和递减等等

( ) 运算符
( ) 运算符用于运算优先级的变更,以及函数的调用。
[ ] 运算符
[ ] 运算符是 间接成员选择 运算符。A [ B ] 这么写的话,会先对 A 求值,然后对 B 求值。将 B 作为字符串,在 A 中查找对应的成员名,并对那个成员进行操作。作为左值使用的时候,对象内的成员 B 如果不存在的话,会被创建。
. 运算符
. 运算符是 直接成员选择 运算符。A.B 这么写的话,会先对 A 求值。在 A 中查找 B 并对找到的成员进行操作。作为左值使用的时候,对象内的成员 B 如果不存在的话,会被创建。
如果省略 . 运算符左侧的表达式,在 with 语句的范围外的话会被当作 global 对象的成员,在 with 语句内侧则会被当作 with 所指定的对象的成员。
++ 运算符
后置的 ++ 运算符是后置的递增运算符。将左侧的表达式加1,加1之前的左侧的表达式的值作为该运算符的结果。
-- 运算符
后置的 -- 运算符是后置的递减运算符。将左侧的表达式减1,减1之前的左侧的表达式的值作为该运算符的结果。
! 运算符
后置的 ! 运算符是 表达式求值运算符。对左侧表达式求值,其结果作为字符串,被当作表达式字符串来解析。那个表达式字符串被解析并求值的结果作为该运算符的结果。解析出的表达式会在 this 上下文 (使用这个运算符的位置的 this) 中执行。
incontextof 运算符
incontextof 运算符会先对左侧表达式求值,然后对右侧表达式求值。将左侧表达式的结果作为对象,将这个对象的上下文部分替换为右侧表达式的结果,替换后的对象作为该运算符的结果。
int 运算符
int 运算符会对右侧的表达式求值,将表达式的值转换为整数作为该运算符的结果。也可以像C语言那样写成 (int) 的形式。
real 运算符
real 运算符会对右侧的表达式求值,将表达式的值转换为实数作为该运算符的结果。也可以像C语言那样写成 (real) 的形式。
string 运算符
string 运算符会对右侧的表达式求值,将表达式的值转换为字符串作为该运算符的结果。也可以像C语言那样写成 (string) 的形式。