JavaScript教学 - 运算子(Operators) - 上
介绍JavaScript中的运算子(Operators)的用法,包含种类、优先顺序、算术运算子(Arithmetic Operator)、指派运算子(Assignment Operator)、位元运算子(Bitwise Operator)和比较运算子(Comparison Operator)。
1. 简介
1.1 运算式
运算式(Expression)或称表达式,能够让直译器理解并执行的程式片段都可以称作运算式, 例如任何的实字或变数名称,以下为一些运算式:
123 i 123 + i x = 123 + i
以下不是运算式:
123 + x = 123 +
1.2 种类
运算式中可透过提供一些数值给运算子(Operator,或运算符)进行运算,进而得到一个运算结果,可以想成类似函式的回传。另外被运算的数值称为运算元(Operand)。
依据运算元的个数,运算子可以分为三种:
- 一元运算子,只有一个运算元,例如:!, ++等。
- 二元运算子,包含两个运算元,大部分都属于这类。
- 三元运算子,包含三个运算元,只有? :运算子属于此类。
而依据性质,可以分为:
- 算术运算子(Arithmetic Operator)
- 指派运算子(Assignment Operator)
- 位元运算子(Bitwise Operator)
- 比较运算子(Comparison Operator)
- 逻辑运算子(Logical Operator)
- 字串运算子(String Operator)
- 特殊运算子(Special Operator)
1.3 优先顺序
结合律 | 运算子 |
---|---|
右 | new |
左 | [] () . |
右 | ++ -- ~ - +(正负号) ! delete typeof void |
左 | * / % |
左 | + - (加减, 字串连接) |
左 | << >> >>> |
左 | < <= > >= <> |
左 | == != === !== |
左 | & |
左 | ^ |
左 | | |
左 | && |
左 | || |
右 | ? : |
右 | = += -= *= /= %= &= |= ^= <<= >>= >>>= |
左 | , |
结合律左右的解释范例如下:
console.log(1 + 2 + '3'); // 33 console.log(1 + '2' + 3); // 123 // 结合律: 右 var a = 1; var b = 2; a = b += 3; // b = 5, a = 5
2. 算术运算子
算术运算子(Arithmetic Operator)就如同数学的四则运算一般,包含以下运算子:
范例 | 名称 | 说明 |
---|---|---|
+a | 正号 | 实际上无作用 |
-a | 负号 | 将a正负变号 |
a + b | 加法 | a和b的总和 |
a - b | 减法 | a减去b |
a * b | 乘法 | a乘上b |
a / b | 除法 | a除以b |
a % b | 取余数 | a除以b的余数(余数的正负号与a相同) |
++a | 前置增值 | a先+1,再回传 |
a++ | 后置增值 | a先回传,再+1 |
--a | 前置减值 | a先-1,再回传 |
a-- | 后置减值 | a先回传,再-1 |
3. 指派运算子
指派运算子(Assignment Operator)符号是(=),你可能会把它想成数学的等于,但实际上不能这样想,正确的意思是:将右边的结果放入左边。
指派运算子会将指派结果回传,也就是指派的内容本身,又因为结合律为右,所以可以将指派的回传结果指派给下个变数,例如
var x, y, z; console.log(y = 1); // 1 x = y = z = 2; console.log(x, y, z); // 2, 2, 2
另外也有具有运算的指派,包含以下运算子:
范例 | 说明 |
---|---|
a += b | a = a + b |
a -= b | a = a - b |
a *= b | a = a * b |
a /= b | a = a / b |
a %= b | a = a % b |
a <<= b | a = a << b |
a >>= b | a = a >> b |
a &= b | a = a & b |
a |= b | a = a | b |
a ^= b | a = a ^ b |
4. 位元运算子
位元运算子(Bitwise Operator)能够对整数的位元进行运算,包含以下运算子:
范例 | 名称 | 说明 |
---|---|---|
a & b | 交集(And) | a和b的位元皆为1的部份为1 |
a | b | 联集(Or) | a或b的位元其中一方为1的部份为1 |
a ^ b | 互斥(Xor) | a和b的位元只有其中一方为1的部份为1 |
~ a | 补数(Not) | a为1的部份为0,为0的部份为1 |
a << b | 左移 | a往左移动b个位元(意同a乘以2的b次方) |
a >> b | 带正负号右移 | a往右移动b个位元,并保留原始正负号(意同a除以2的b次方之整数) |
a >>> b | 补0右移 | a往右移动b个位元,无视正负号,左边的位元一律补0 |
JavaScript中处理位元运算时,变数一律视为32位元的数值来处理,当位移数超过32位元时,会取32的余数来进行运算,以下是一些范例:
function toBitsString(num) { var str = ''; while(num) { str = (num & 1) + str; num = num >>> 1 } return str; } function toBits(num) { var str = toBitsString(num) for(var i = str.length;i < 8;++i) str = '0' + str; return str.slice(-8); } var a = 55; var b = 66; console.log(toBits(a)); // 00110111 console.log(toBits(b)); // & 01000010 //----------- console.log(toBits(a & b)); // 00000010 : 2 // 00110111 // | 01000010 //----------- console.log(toBits(a | b)); // 01110111 : 119 // 00110111 // ^ 01000010 //----------- console.log(toBits(a ^ b)); // 01110101 : 117 // ~ 00110111 //------------ console.log(toBits(~a)); // 11001000 : -56 // 00110111 << 2 //------------ console.log(toBits(a << 2)); // 11011100 : 220 // 00110111 >> 33 //------------ console.log(toBits(a >> 33)); // 00011011 : 27 console.log(-4 >> 1); // -2 console.log(-4 >>> 1); // 2147483646
JavaScript的数字类别的toString函式能够将数字依据指定的进位制输出字串,但是它是把他视为具有正负号的数字处理,而不是作为位元组处理,所以必须自行实作转换:
var a = -56; console.log(a.toString(2)); // -111000 console.log(a.toString(16)); // -38 console.log(toBitsString(a)); // 11111111111111111111111111001000
5. 比较运算子(Comparison Operator)
比较运算子(Comparison Operator)可以比较两个值,并将结果以布林回传,包含以下运算子:
范例 | 名称 | 说明 |
---|---|---|
a == b | 相等 | 如果a和b的值相等则为true |
a === b | 完全相等 | 如果a和b的值与型别都相等则为true,物件、阵列和函式必须是同一个物件才为true |
a != b | 不相等 | 如果a和b的值不相等则为true |
a !== b | 不完全相等 | 如果a和b的值或型别不相等则为true |
a < b | 小于 | 如果a小于b则为true |
a > b | 大于 | 如果a大于b则为true |
a <= b | 小于等于 | 如果a小于等于b则为true |
a >= b | 大于等于 | 如果a大于等于b则为true |
只有以下情形完全相等才为true:
- 两者皆是非NaN数字型别且数值相等。
- 两者皆是字串型别且内容相等。
- 两者皆是布林型别且数值相等。
- 两者都指向同一物件、阵列或函式。
- 两者皆是null。
- 两者皆是undefined。
进行相等运算比较时,会根据以下的规则来做处理:
- undefined或null只和undefined或null相等。
- 其他情况依据非相等运算规则处理。
进行非相等运算比较时,会根据以下的规则来做处理:
- 运算元包含undefined和NaN则为false。
- 两者皆为字串,则以字串比较。(Unnicode编码比较)
- 空阵列和字串比较,空阵列优先转为字串比较。
- 一方为数字或能转换为数字,则以数字比较。(另一方无法转换则为false)
- 其他情况转换为字串,以字串比较。
- 若不能转换成数字或字串,则为false。
一些范例如下:
console.log(10 == '1e1'); // true, 数字比较 console.log('b' > 'a'); // true console.log('' == 0); // true, 数字比较 console.log(false == null); // false, undefined或null只和undefined或null相等 console.log(undefined == null); // true console.log(2 > true && true > 0); // true, 数字比较, true -> 1 console.log(1 > null && null > -1); // true, 数字比较, null -> 0
console.log(false > -1); // true, 数字比较
console.log([] > -1); // true, 数字比较, 空阵列转为0
console.log(false > '-1'); // true, 数字比较
console.log([] > '-1'); // false, 字串比较!! function A() { } A.prototype.toString = function () { return 'A'; }; var a = new A(); var s = {}; // [object Object] console.log(a < s); // true, 字串比较 'A' < '[object Object]' console.log(a == 'A'); // true console.log(s > '\xff'); // false var b = [55]; var c = [66]; var d = [55,66]; console.log(b < c); // true, 字串比较 '55' < '66' console.log(b == '55'); // true console.log(d == '55,66'); // true
延伸阅读