上篇文章分享了 JavaScript 的基本语法、严格模式的启用,还有变量、五大基本数据类型以及所定义的一些关键字保留字等。在这篇文章里,你可以了解到 JavaScript 中的各类操作符,这些操作符有些很熟悉,一直在用,有些可能平时不太注意,但也会多少用到。

花式操作符

操作符,顾名思义,就是对数据进行操作。JavaScript 能参与运算的操作符很多,有一元操作符、位操作符、乘性操作符等等,接下来一一介绍下这些操作符,很多都是挺熟悉经常在用的。

一元操作符

最基本的就是一元操作符,意思是只能操作一个数值。我们最常见到的就是 ++-- 了,它可以对一个数进行递增或递减。看下面的例子:

1
2
var num = 1;
++num; // 2

也可写成 num = num + 1 是一样的效果,相应地,-- 操作符就是 --numnum = num - 1 。这里特别要注意的是两个操作符的放置位置:如果在变量前面,则先自增/自减再去执行语句操作,而如果在后面,则先执行语句,完了在自增/自减。来看下面的例子:

1
2
3
4
5
var a = 10;
var b = 2;
var c = --a + b // 11,a 先减去1在加 b
var d = a-- + b // 11, 由于上条语句 --a 使得 a 变成 9 ,在加 b 等于 11
console.log(a) // 此时 a 已经是 8

仔细体会下上面语句的执行结果,就能明白 ++-- 在变量的不同位置其效果是不一样的。

除此之外,还有一元操作符 +- ,普通的加减都知道的了。这里需要注意的是这两个符号可以用来转换数据类型。看例子:

1
2
3
4
5
6
7
8
9
10
11
12
var a = false;
var b = 1;
var c = {
valueOf: function() {
return -1;
}
}
+a // 0
+b // 1
-b // -1
+c // -1
-c // 1

这种隐式转换在写代码时经常用到。

位操作符

~ 表示按位非,它会对一个数的二进制进行操作,返回它的反码,最终得到的结果就是原数值的负值减 1。所以 ~25 的结果就是 -26,那为什么不直接对 25 取负值然后在减 1 不就好了?也是可以的,但是用 ~ 操作符是在计算机底层进行二进制操作,所以速度更快,追求性能的话首选。

& 表示按位与,同样是二进制操作。只有当两个数位同时为 1 时才返回 1,其余都都返回 0 。例如求 25 & 3,先把 25 和 3 分别以二进制表示,我们知道二进制只有 0 和 1 两个表示,将它们对应的位进行运算,同时为 1 则返回 1,否则都是 0 ,最后将得到的二进制数重新翻译成十进制就得到结果了。

| 表示按位或,与 & 类似的二进制操作,不过这次是只有当两个位数同时为 0 才返回 0,其余都会返回 1。所以求 25 | 3,你不妨写几句代码,运行下看看是什么结果,上次说了,用 toString(n) 方法可以返回一个数的 n 进制表示。

^ 按位异或,与 | 的不同在于,只有当两个数位同时为 1 或 同时为 0 时会返回 0,其余都返回 1 。

<< 左移操作符,将一个数向左移动得到的结果,移动后的空位会以 0 来填充。例如求 2 << 5 ,2 的二进制是 10,向左移动 5 为,就相当于在后面补 5 个 0,得到 10 00000 转换成十进制就是 64,所以 2 << 5 就是 64。

>> 右移运算符,将一个数向右移动得到的结果,移动后的空位会以符号位来填充。例如将上面的 64 >> 5 就相当于让 10 00000 向右移动五位,就是 10 ,左边空出来的位以符号位 0 填充,可以忽略,所以得到的结果是 2 。

>>> 无符号右移,跟 >> 一样,只不过它移动后的空位会以0来填充,所以右移后的数值会非常大,具体可以自己去用代码验证下。

布尔操作符

布尔符应该很熟悉了,有 3 个,分别是非!,逻辑与&& 和逻辑或||

! 取反符,将一个数值转换为布尔值,在取反。所以!true 等于 false,!0 等于 true 等等。这个符号经常用在 if 等语句中。

&& 逻辑与,当且仅当两个值都为 true 时才返回 true,其余都返回 false 。经常用在 if 语句的条件判断中,也就是两个条件都要满足时才予以执行。它是短路操作符,也就是说,如果第一个值是 false 了,那么第二个值无论是什么,都不会再去求它,结果已经是返回 false 了。

|| 逻辑或,也是短路操作符,当且仅当两个值都为 false 时才返回 false,其余情况都会返回 true。这个操作符大有用处,在定义变量的时候,经常会用到下面这条语句:

1
var str = result || '';

这条语句的意思是优先把这个 result 的值赋给 str,如果找不到它,那就默认赋个空字符串给它,这样就避免了值为 undefined 或 null,从而避免遇到执行错误。

乘性操作符

这个同样很熟悉,三个乘性操作符分别为 */ 以及 % 。关于乘和除,平常用的够多了,就跟数学的乘除一样,需要注意的就是一些特殊情况,如 NaN 值,infinity 值以及非数值如字符串,这些参与乘除运算会出现什么样的结果,你可以动手去试下,印象会更深。

% 对一个数进行求模。举个例子,21 % 5 会得到 1,为什么呢?21 除以 5 不能整除,只能得到商 4,最后余数为 1,所以记住 % 操作符就是去取余数。那请问 2 % 5 会得到多少?你可以去试下。

加性操作符

就两个符号,+- 。跟数学的加减一样,但比较有意思的是涉及到非数值类型,如字符串,看看下面的代码

1
2
var result = 5 + '5';
console.log(result); // '55'

是的,你没看错,5 去加字符串的 5 ,最终得到的是 55 ,这个 55 是字符串的 55 ,也就是说,解释器先将第一个数值转换成了字符串,然后在与第二个字符串想 +,最终得到的是一个拼接的字符串,所以是 '55'

而对于减法符号 -,就不一样了,前面提到的将数值转换成字符串在进行加,而如果一个数值去跟一个字符串数值相减,结果不会是字符串,而是一个正常的数值,例如 5 - '5' 会得到 0,解释器将后面的字符串转成了数值,然后进行相减。所以,- 操作符用处很大,它可以进行隐式转换,即将一个字符串转成数值,不必去调用方法,只需一个符合就行。

关系操作符

关系操作符有 <> 以及 >=<= 。它们的用处是比较两个字符串或数字之间的大小,对于字符串而言,比较是按照字符串编码值来,所以会出现 "Brick" < "apple",为什么会这样呢?因为 ASCII 编码中大写字母 A 是从数字 65 开始计的,而小写字母 a 从 91 开始,因为「B」的编码数值小于「a」,所以"Brick" < "apple",解决方法是使用 toLowerCase() 转换大小写在比较;对于数值而言,同样会出现如 "23" < "3" 这样子,因为 2 < 3 而导致的,解决方法是转换为基本数据类型中的 Number 类型进行比较。

相等操作符

分为相等 == 和全等 === 两个操作符。前者会自动转换数据类型进行比较,例如 "5" == 5 返回结果为 true,因为字符串会被转换为数值然后参与比较;而如果是 "5" === 5 就是 false 了,=== 不会进行类型的转换,该怎么比较就怎么比较,这也是我们想要的结果,所以比较推荐使用全等符。

条件操作符

compare? result1:result2;俗称三目运算符,意思是执行这个 compare 语句,如果为 true 的话返回 result1 ,否则返回 result2。相信你已经猜到了,它可以适时替代掉 if - else 语句,有相同的效果。

赋值操作符

分别是 =+= ,用来赋值的符号,后者 += 在用的时候例如 x += 1,与 x = x + 1 是一样的,设计这个符号就是为了简化操作,没什么特别的地方。

逗号操作符

逗号操作符可以用来声明多个变量,比如连续声明四五个变量:

1
2
3
4
5
var x = 0,
y = 0,
z = 0,
num = 0,
count = 0;

很方便地声明变量而不用写多条语句。特别注意的是,假如你同时给一个变量赋了多个值,最终保留最后一个,所以 var num = (5,4,2,3,0) ,最终 num 的值就是 0 。

未完待续… …

参考资料

《JavaScript 高级程序设计》 [美] Nicholas C.Zakas 著