表达式(expression)是JavaScript中的一个短语,JavaScript解释器会将其计算出一个结果。
将简单表达式组合成复杂表达式最常用的方法就是使用运算符(operator)。运算符按照特定的运算规则对操作数进行运算,并计算出新值。
1、表达式
1.1原始表达式
原始表达式是表达式的最小单位---它们不包含其他表达式。
JavaScript中的原始表达式包含常量、直接量、变量或关键字。
直接量是直接在程序中出现的常数值。
1.2
"hello"
保留字
true
flase
null
this
变量
i
num
1.2对象和数组的初始化表达式
对象和数组初始化表达式实际上是一个新创建的对象和数组。也可称为“
对象直接量”和“
数组直接量”。
var arr = []
var p = {};
注意:JavaScript对数组初始化表达式和对象初始化表达式求值的时候,数组初始化表达式和对象初始化表达式的元素表达式也都会各自计算一次。也就是说,元素表达式每次计算的值有可能是不同的。
1.3函数定义表达式
函数定义表达式(函数直接量)定义一个JavaScript函数。表达式的值是这个新定义的函数。
var f = function(){}
1.4属性访问表达式属性访问表达式运算得到一个对象属性或一个数组元素的值。
var arr =[1];
var p = {x:1}
arr[0]
p.x
注意:在“.”和“[”之前的表达式总是会首先计算,如果计算结果是null或undefined,表达式会抛出一个类型错误异常,因为这两个值都不能包含任何属性。
1.5调用表达式
JavaScript中的调用表达式是一种调用函数或方法的语法表示。
f()
a.sort()
1.6对象创建表达式对象创建表达式创建一个对象并调用一个函数(这个函数称做构造函数)初始化新对象的属性。
new Object()
JavaScript中的大多数运算符是一个二元运算符。不过,JavaScript支持一个三元运算符(ternary operator),条件判断运算符“?:”,它将三个表达式合并成一个表达式。
2算术运算符
加法运算符(Addition):x + y
减法运算符(Subtraction): x - y
乘法运算符(Multiplication): x * y
除法运算符(Division):x / y
余数运算符(Remainder):x % y
自增运算符(Increment):++x 或者 x++
自减运算符(Decrement):--x 或者 x--
数值运算符(Convert to number): +x
负数值运算符(Negate):-x
2.1 加法运算符
加法运算符(+)可以对两个数字做加法,也可以做字符串连接操作。
1 + 2 //3
'hello' + ' world' //hello world
加法运算符的行为表现为:
- 如果其中一个操作数是对象,则对象会遵循对象到原始值的转换规则转为为原始类值;日期对象通过toString()方法执行转换,其他对象则通过valueOf()方法执行转换,如果结果还不是原始类型的值,再执行toString方法;
- 在进行了对象到原始值的转换后,如果其中一个操作数是字符串的话,另一个操作数也会转换字符串,然后进行字符串连接。
- 否则,两个操作数都将转换为数字(或者NaN),然后进行加法操作。
2.2一元算术运算符
一元算术运算符作用于一个单独的操作数,并产生一个新增。
在JavaScript中,一元算术运算符具有很高的优先级,而且都是右结合。
(1)一元加法(+)
一元加法运算符把操作数转换为数字(或者NaN),并返回这个转换后的数字。如果操作数本身就是数字,则直接返回这个数字。
(2)一元减法(-)
当“-"用做一元运算符时,它会根据需要把操作数转换为数字,然后改变运算结果的符号。
(3)递增(++)
递增“++”运算符对操作数进行增量(加-)操作。运算符将操作数转换为数字,然后给数字加1,并将加1后的数值重新赋值给变量、数组元素或对象属性。
前增量
运算符在操作数之前。
运算符在操作数之后。
后增量会先返回变量操作前的值,再进行自增操作;前增量会先进行自增操作,再返回变量操作后的值。
var a = 1;
a++; // 1
++a; // 2
注意:由于JavaScript会自动进行分号补全,因此不能再后增量运算符和操作数直接插入换行符。
递减(--)
递减运算符和”++“运算符一样,返回值也依赖于它相对操作数的位置。
var a = 3;
a--; //3
--a; //2
3、关系运算符、逻辑运算符、赋值运算符、位运算符
3.1关系表达式
关系运算符用于测试两个值之间的关系,根据关系是否存在而返回true或false。
== 相等
=== 严格相等
!= 不相等
!== 严格不相等
< 小于
<= 小于或等于
> 大于
>= 大于或等于
相等和不等运算符"=="和"==="运算符用于比较两个值是否相等。
"!="和"!=="运算符的检测规则是"=="和"==="运算符的求反。
比较运算符
小于(<)
大于(>)
小于等于(<=)
大于等于(>=)
3.2逻辑表达式逻辑运算符是对操作数进行布尔算术运算,经常和关系运算符一起配合使用。
逻辑与(&&)
且运算符的运算规则是:如果第一个运算子的布尔值为true,则返回第二个运算子的值(注意是值,不是布尔值);如果第一个运算子的布尔值为false,则直接返回第一个运算子的值,且不再对第二个运算子求值。
true && 1; //1
'' && 'f' //""
逻辑或(||)
或运算符(||)的运算规则是:如果第一个运算子的布尔值为true,则返回第一个运算子的值,且不再对第二个运算子求值;如果第一个运算子的布尔值为false,则返回第二个运算子的值。
'a' || '' // "a"
'' || 'a' //"a"
逻辑非(!)
取反运算符形式上是一个感叹号,用于将布尔值变为相反值,即true变成false,false变成true。
!true; //false
!false; //true
对于非布尔值的数据,取反运算符会自动将其转为布尔值。规则是,以下六个值取反后为true,其他值取反后都为false。
undefined
null
false
0(包括+0和-0)
NaN
空字符串('')
3.3.赋值表达式JavaScript使用“=”运算符来给变量或熟悉赋值。
带操作的赋值运算
x += y // 等同于 x = x + y
x -= y // 等同于 x = x - y
x *= y // 等同于 x = x * y
x /= y // 等同于 x = x / y
x %= y // 等同于 x = x % y
x >>= y // 等同于 x = x >> y
x <<= y // 等同于 x = x << y
x >>>= y // 等同于 x = x >>> y
x &= y // 等同于 x = x & y
x |= y // 等同于 x = x | y
x ^= y // 等同于 x = x ^ y
3.4位运算符
位运算符用于直接对二进制进行计算。
或运算(or):符号为|,表示若两个二进制位都为0,则结果为0,否则为1。
与运算(and):符号为&,表示若两个二进制位都为1,则结果为1,否则为0。
否运算(not):符号为~,表示对一个二进制位取反。
异或运算(xor):符号为^,表示若两个二进制位不相同,则结果为1,否则为0。
左移运算(left shift):符号为<<。
右移运算(right shift):符号为>>。
带符号位的右移运算(zero filled right shift):符号为>>>
有一点需要特别注意,位运算符只对整数起作用,如果一个运算子不是整数,会自动转为整数后再执行。
4、其他运算符
4.1in运算符
in运算符希望它的左操作数是一个字符串或可以转换为字符串,希望它的右操作数是一个对象。如果右侧的对象拥有一个名为左操作数值的属性名,则返回true。
var o = {x:1};
"x" in o //true
4.2instanceof运算符
instanceof运算符希望左操作数是一个对象,右操作数标识对象的类。如果左侧的对象是右侧类的实例,则表达式返回true。
var a = new Array();
a instanceof Object; //true
注意:所有对象都是Object的实例。
4.3条件运算符(?:)
三元条件运算符用问号(?)和冒号(:),分隔三个表达式。如果第一个表达式的布尔值为true,则返回第二个表达式的值,否则返回第三个表达式的值。
x>0 ? x : -x; //求x的绝对值
4.4typeof运算符typeof是一元运算符,用来判断类型。
typeof 1 // 'number'
4.5delete 运算符delete是一元操作符,它用来删除对象的属性或数组元素。
var o={x:1}
delete o.x;
"x" in o //false
4.6void运算符void是一元运算符,它出现在操作数之前,操作数可以是任意类型。操作数会照常计算,但忽略计算结果并返回undefined。
void 0 //undefined
void(0) //undefined
var a = 1;
void (a=2);
a //2
这个运算符主要是用于书签工具(bookmarklet),以及用于在超级链接中插入代码,目的是返回undefined可以防止网页跳转。
<a href="javascript:void(0)"></a>
4.8逗号运算符(,)逗号运算符是二元运算符,它的操作数可以是任意类型。它首先计算左操作数,然后计算右操作数,最后返回右操作数的值。
'a','b' //"b"
var a = 0;
var b = (a++,5);
a //1
b //5
5、运算顺序
5.1优先级
JavaScript各种运算符的优先级别(Operator Precedence)是不一样的。优先级高的运算符先执行,优先级低的运算符后执行。
5.2圆括号
圆括号(())可以用来提高运算的优先级,因为它的优先级是最高的,即圆括号中的表达式会第一个运算。
注意:因为圆括号不是运算符,所以不具有求值作用,只改变运算的优先级。
对于优先级别相同的运算符,大多数情况,计算顺序总是从左到右,这叫做运算符的“左结合”(left-to-right associativity),即从左边开始计算。
但是少数运算符的计算顺序是从右到左,即从右边开始计算,这叫做运算符的“右结合”(right-to-left associativity)。其中,最主要的是赋值运算符(=)和三元条件运算符(?:)。