4.7 运算符概述
JavaScript的运算符用于算术表达式、比较表达式、赋值表达式等。
运算符包括关键字运算符和标点运算符。
运算符 | 操作 | A | N | 类型 |
++
--
-
+
~
!
delete
typeof
void
|
前/后增量
前、后减量
求反
转换为数字
按位求反
逻辑非
删除属性
检测操作数类型
返回undefined值
|
R
R
R
R
R
R
R
R
R
|
1
1
1
1
1
1
1
1
1
|
lval ---> num
lval ---> num
num ---> num
num ---> num
int ---> int
bool ---> bool
lval ---> bool
any ---> str
any ---> undef
|
* / % | 乘 除 求余 | L | 2 | num,num ---> num |
+ -
-
|
加 、 减
字符串连接
|
L
L
|
2
2
|
num , num ---> num
str,str ---> str
|
<<
>>
>>>
|
左移位
有符号右移
无符号右移
|
L
L
L
|
2
2
2
|
int,int ---> int
int,int ---> int
int,int ---> int
|
<,<=,>,>=
<,<=,>,>=
instanceof
in
|
比较数字顺序
比较在字母表中的顺序
比较对象类
比较属性是否存在
|
L
L
L
L
|
2
2
2
2
|
num.num ---> bool
str,str ---> bool
obj,func --->bool
str,obj ---> bool
|
==
!=
===
!==
|
判断相等
判断不等
判断恒等
判断非恒等
|
L
L
L
L
|
2
2
2
2
|
any,any ---> bool
any,any ---> bool
any,any ---> bool
any,any ---> bool
|
& | 按位与 | L | 2 | int ,int ---> int |
^ | 按位异或 | L | 2 | int,int ---> int |
| | 按位或 | L | 2 | int,int --->int |
&& | 逻辑与 | L | 2 | any,any ---> any |
|| | 逻辑或 | L | 2 | any,any --->any |
?: | 条件运算符 | R | 3 | bool,any,any--->any |
=
*=,/=,%=,+=,-=,&=
^=,|=,<<=,>>=,>>>=
|
变量、对象属性赋值
运算且赋值
|
R
R
|
2
2
|
lval,any ---> any
lval,any ---> any
|
'
|
忽略第一个操作数,
返回第二个操作数
| L | 2 | any,any ---> any |
按照运算符的优先级排序,前面的运算符优先级高于后面的运算符优先级。
被水平分割线分隔开的运算符具有不同的优先级。
标题为A的列表示运算符的结合性,L:从左至右结合 R:从右至左结合。
标题N的列:操作数的个数。
lval--left-value 左值
4.7.1 操作符的个数
根据个数分类:
一元运算符:例如:-x (一个参数)
二元运算符:例如:* + (两个参数)
三元运算符:唯一一个: ?:
|
4.7.2 操作数类型和结果类型
一些运算符可以作用于任何数据类型,但仍然希望他们的操作数是指定的数据类型,并且大多数运算符返回一个特定类型的值。
JavaScript运算符通常会根据需要对操作数进行类型转换:例如 “3”* “5” ---> 3 * 5 返回数字15,而不是“15”,对于那些希望操作数是布尔类型的操作符来说,他们的操作数可以是任意类型。
有一些运算符对操作类型有着不同程度的依赖。例如:
加法运算符,“+”可以对数字进行加法运算,也可以对字符串进行连接;
“<”比较运算符可以根据操作数类型的不同对数字进行大小值的比较,也可以比较字符在字母表中的次序先后。
|
4.7.3 左值
lvalue(left-value) -- 表达式只能出现在赋值运算符的左侧;
表中的赋值运算符和其他少量运算符期望他们的操作数是lval类型,在JavaScript中,变量、对象属性和数组元素均是左值。
|
4.7.4 运算符的副作用
计算一个简单的表达式不会对程序的运行状态造成任何影响,程序后续执行的运算也不会受该计算的影响。而有一些表达式具有很多副作用,前后的表达式运算会相互影响,例如赋值运算符“=”,如果给一个变量或者属性赋值,那些使用这个变量或属性的表达式的值会发生变化, “++” “--”与之类似,因为它们包含隐性的赋值。 “delete”运算符同样有副作用:删除一个属性就像(但不完全一样)给这个属性赋值undefined;其它JavaScript运算符没有副作用。
但函数调用表达式和对象创建表达式有些特别,在函数体或者构造函数内部运用了这些运算符并产生副作用的时候,我们说函数调用表达式和对象创建表达式是有副作用的。、
|
4.7.5 运算符优先级
表中的运算符按照优先级从高到低排序,每个水平分割线内的一组运算符具有相同的优先级。运算符优先级控制着运算符的执行顺序。优先级高的执行总是先于优先级低的运算符。
运算符的优先级可以通过显式使用圆括号来重写,但是属性访问表达式和调用表达式的优先级比表中的所有运算符都要高。
如果不确定所使用过的运算符的优先级,最简单的方法就是使用圆括号强行指定运算次序(赋值运算的优先级非常低,通常总是最后执行)。
|
4.7.6 运算符的结合性
表中标题为A的列说明了运算符的结合性。L从左至右结合,R从右至左结合。
结合性指定了在多个具有同样优先级的运算符表达式中的运算顺序。
例如:
w = x-y-z ==> w = ((x-y)-z);
x = ~-y; ==> x =~(-y);
|
4.7.7 运算顺序
运算符的优先级和结合性规定了它们在复杂的表达式中的运算顺序,但没有规定子表达式的计算过程中的运算顺序。JavaScript总是严格按照从左至右的顺序计算表达式:
例如: w = x + y*z, 首先计算子表达式w,然后计算x,y,z,然后计算完毕右边 的值赋给左边。
只有在任何一个表达式具有副作用而影响到其他表达式的时候,其求值顺序才会和看上去有所不同。如果表达式x中的一个变量自增1,这个变量在表达式z中使用,那么实际上是先计算了x的值再计算z的值。例如:
b = (a++)+a; a=1
|