表达式和运算符
表达式是运算符和操作数(operand)的集合,或者是常量。
通常用以下格式书写。
表达式;
像这样在表达式的后面加上分号(;)的话,该表达式会被当场求值( = 执行 ),而产生的结果会被丢弃。
例:
a=b;
//由于=运算符的作用,b变量的值被代入到a变量中
func();
//由于()运算符的作用,func作为函数被调用,函数的返回值被舍弃
1+3;
//由于+运算符的作用,1和3被求和,其结果被舍弃(实际上
//因为这个表达式没有意义,它不会被执行)
真(true) 和 假(false)
有些运算符用于对真和假 (逻辑值) 进行处理。运算结果为 0 是代表 假(false) ,非0 是代表 真(true) 。
对字符串判断真假的时候,空字符串为 假、字符串非空的时候会被尝试转换为数值。如果转换成功就以转换结果的数值来判断真假,转换不成功则认定为 假。
运算符
下面以优先级由低到高的顺序对各个运算符以下进行说明。
if 运算符
条件运算符 if
会对其右侧的表达式求值,如果结果为 真 ,就会对左侧的表达式求值。
例:
a=bifb!=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) 的形式。