運(yùn)算符的定義和分類
運(yùn)算符的定義
運(yùn)算符:也叫操作符,是一種符號(hào)。通過(guò)運(yùn)算符可以對(duì)一個(gè)或多個(gè)值進(jìn)行運(yùn)算,并獲取運(yùn)算結(jié)果。
表達(dá)式:由數(shù)字、運(yùn)算符、變量的組合(組成的式子)。
表達(dá)式最終都會(huì)有一個(gè)運(yùn)算結(jié)果,我們將這個(gè)結(jié)果稱為表達(dá)式的返回值。
比如:+、*、/、( 都是運(yùn)算符,而(3+5)/2則是表達(dá)式。
比如:typeof 就是運(yùn)算符,可以來(lái)獲得一個(gè)值的類型。它會(huì)將該值的類型以字符串的形式返回,返回值可以是 number string boolean undefined object。
運(yùn)算符的分類
JS 中的運(yùn)算符,分類如下:
- 算數(shù)運(yùn)算符
- 自增/自減運(yùn)算符
- 一元運(yùn)算符
- 邏輯運(yùn)算符
- 賦值運(yùn)算符
- 比較運(yùn)算符
- 三元運(yùn)算符(條件運(yùn)算符)
下面來(lái)逐一講解。
算數(shù)運(yùn)算符
算術(shù)運(yùn)算符:用于執(zhí)行兩個(gè)變量或值的算術(shù)運(yùn)算。
常見(jiàn)的算數(shù)運(yùn)算符有以下幾種:
| 運(yùn)算符 | 描述 |
|---|---|
| + | 加、字符串連接 |
| - | 減 |
| * | 乘 |
| / | 除 |
| % | 獲取余數(shù)(取余、取模) |
求余的舉例:
假設(shè)用戶輸入345,怎么分別得到3、4、5這三個(gè)數(shù)呢?
答案:
得到3的方法:345 除以100,得到3.45然后取整,得到3。即:parseInt(345/100)
得到4的方法:345 除以100,余數(shù)是45,除以10,得到4.5,取整。即:parseInt(345 % 100 / 10)
得到5的方法:345 除以10,余數(shù)就是5。即:345 % 10
算數(shù)運(yùn)算符的運(yùn)算規(guī)則
(1)先算乘除、后算加減。
(2)小括號(hào)( ):能夠影響計(jì)算順序,且可以嵌套。沒(méi)有中括號(hào)、沒(méi)有大括號(hào),只有小括號(hào)。
(3)百分號(hào):取余。只關(guān)心余數(shù)。
舉例1:(取余)
console.log(3 % 5);
輸出結(jié)果為3。
舉例2:(注意運(yùn)算符的優(yōu)先級(jí))
var a = 1 + 2 * 3 % 4 / 3;
結(jié)果分析:
原式 = 1 + 6 % 4 / 3 = 1 + 2 / 3 = 1.66666666666666
補(bǔ)充:關(guān)于算數(shù)運(yùn)算符的注意事項(xiàng),詳見(jiàn)上一篇文章里的“數(shù)據(jù)類型轉(zhuǎn)換”的知識(shí)點(diǎn)。
浮點(diǎn)數(shù)運(yùn)算的精度問(wèn)題
浮點(diǎn)數(shù)值的最高精度是 17 位小數(shù),但在進(jìn)行算術(shù)計(jì)算時(shí),會(huì)丟失精度,導(dǎo)致計(jì)算不夠準(zhǔn)確。比如:
console.log(0.1 + 0.2); // 運(yùn)算結(jié)果不是 0.3,而是 0.30000000000000004
console.log(0.07 * 100); // 運(yùn)算結(jié)果不是 7,而是 7.000000000000001
因此,不要直接判斷兩個(gè)浮點(diǎn)數(shù)是否相等。
自增和自減
自增 ++
自增分成兩種:a++和++a。
(1)一個(gè)變量自增以后,原變量的值會(huì)立即自增1。也就是說(shuō),無(wú)論是 a++ 還是++a,都會(huì)立即使原變量的值自增1。
(2)我們要注意的是:a是變量,而a++和++a是表達(dá)式。
那這兩種自增,有啥區(qū)別呢?區(qū)別是:a++ 和 ++a的值不同:(也就是說(shuō),表達(dá)式的值不同)
-
a++這個(gè)表達(dá)式的值等于原變量的值(a自增前的值)。你可以這樣理解:先把 a 的值賦值給表達(dá)式,然后 a 再自增。 -
++a這個(gè)表達(dá)式的值等于新值 (a自增后的值)。 你可以這樣理解:a 先自增,然后再把自增后的值賦值給表達(dá)式。
自減 --
原理同上。
開(kāi)發(fā)時(shí),大多使用后置的自增/自減,并且代碼獨(dú)占一行,例如:num++,或者 num--。
代碼舉例
var n1 = 10;
var n2 = 20;
var result1 = n1++;
console.log(n1); // 11
console.log(result1); // 10
result = ++n1;
console.log(n1); //12
console.log(result); //12
var result2 = n2--;
console.log(n2); // 19
console.log(result2); // 20
result2 = --n2;
console.log(n2); // 18
console.log(result2); // 18
一元運(yùn)算符
一元運(yùn)算符,只需要一個(gè)操作數(shù)。
常見(jiàn)的一元運(yùn)算符如下。
typeof
typeof就是典型的一元運(yùn)算符,因?yàn)楹竺嬷桓粋€(gè)操作數(shù)。
舉例如下:
var a = '123';
console.log(typeof a); // 打印結(jié)果:string
正號(hào) +
(1)正號(hào)不會(huì)對(duì)數(shù)字產(chǎn)生任何影響。比如說(shuō),2和+2是一樣的。
(2)我們可以對(duì)一個(gè)其他的數(shù)據(jù)類型使用+,來(lái)將其轉(zhuǎn)換為number【重要的小技巧】。比如:
var a = true;
a = +a; // 注意這行代碼的一元運(yùn)算符操作
console.log('a:' + a);
console.log(typeof a);
console.log('-----------------');
var b = '18';
b = +b; // 注意這行代碼的一元運(yùn)算符操作
console.log('b:' + b);
console.log(typeof b);
打印結(jié)果:
a:1
number
-----------------
b:18
number
負(fù)號(hào) -
負(fù)號(hào)可以對(duì)數(shù)字進(jìn)行取反。
邏輯運(yùn)算符
邏輯運(yùn)算符有三個(gè):
-
&&與(且):兩個(gè)都為真,結(jié)果才為真。 -
||或:只要有一個(gè)是真,結(jié)果就是真。 -
!非:對(duì)一個(gè)布爾值進(jìn)行取反。
連比的寫(xiě)法:
來(lái)看看邏輯運(yùn)算符連比的寫(xiě)法。
舉例1:
console.log(3 < 2 && 2 < 4);
輸出結(jié)果為false。
舉例2:(判斷一個(gè)人的年齡是否在18~60歲之間)
var a = prompt("請(qǐng)輸入您的年齡");
alert(a>=18 && a<= 65);
PS:上面的這個(gè)a>=18 && a<= 65千萬(wàn)別想當(dāng)然的寫(xiě)成18<= a <= 65,沒(méi)有這種語(yǔ)法。
注意事項(xiàng)
(1)能參與邏輯運(yùn)算的,都是布爾值。
(2)JS中的&&屬于短路的與,如果第一個(gè)值為false,則不會(huì)看第二個(gè)值。舉例:
//第一個(gè)值為true,會(huì)檢查第二個(gè)值
true && alert("看我出不出來(lái)!!"); // 可以彈出 alert 框
//第一個(gè)值為false,不會(huì)檢查第二個(gè)值
false && alert("看我出不出來(lái)??!"); // 不會(huì)彈出 alert 框
(3)JS中的||屬于短路的或,如果第一個(gè)值為true,則不會(huì)看第二個(gè)值。舉例:
(4)如果對(duì)非布爾值進(jìn)行邏輯運(yùn)算,則會(huì)先將其轉(zhuǎn)換為布爾值,然后再操作。舉例:
var a = 10;
a = !a;
console.log(a); // false
console.log(typeof a); // boolean
上面的例子,我們可以看到,對(duì)非布爾值進(jìn)行!操作之后,返回結(jié)果為布爾值。
非布爾值的與或運(yùn)算【重要】
之所以重要,是因?yàn)樵趯?shí)際開(kāi)發(fā)中,我們經(jīng)常用這種代碼做容錯(cuò)處理或者兜底處理。
非布爾值進(jìn)行與或運(yùn)算時(shí),會(huì)先將其轉(zhuǎn)換為布爾值,然后再運(yùn)算,但返回結(jié)果是原值。比如說(shuō):
var result = 5 && 6; // 運(yùn)算過(guò)程:true && true;
console.log('result:' + result); // 打印結(jié)果:6(也就是說(shuō)最后面的那個(gè)值。)
上方代碼可以看到,雖然運(yùn)算過(guò)程為布爾值的運(yùn)算,但返回結(jié)果是原值。
那么,返回結(jié)果是哪個(gè)原值呢?我們來(lái)看一下。
與運(yùn)算的返回結(jié)果:(以兩個(gè)非布爾值的運(yùn)算為例)
- 如果第一個(gè)值為false,則直接返回第一個(gè)值;不會(huì)再往后執(zhí)行。
- 如果第一個(gè)值為true,則返回第二個(gè)值(如果所有的值都為true,則返回的是最后一個(gè)值)。
或運(yùn)算的返回結(jié)果:(以兩個(gè)非布爾值的運(yùn)算為例)
- 如果第一個(gè)值為true,則直接返回第一個(gè)值;不會(huì)再往后執(zhí)行。
- 如果第一個(gè)值為false,則返回第二個(gè)值((如果所有的值都為false,則返回的是最后一個(gè)值)。
實(shí)際開(kāi)發(fā)中,我們經(jīng)常是這樣來(lái)做「容錯(cuò)處理」的:
當(dāng)成功調(diào)用一個(gè)接口后,返回的數(shù)據(jù)為 result 對(duì)象。這個(gè)時(shí)候,我們用變量 a 來(lái)接收 result 里的圖片資源。通常的寫(xiě)法是這樣的:
if (result.resultCode == 0) {
var a = result && result.data && result.data.imgUrl || 'http://img.smyhvae.com/20160401_01.jpg';
}
上方代碼的意思是,獲取返回結(jié)果中的result.data.imgUrl這個(gè)圖片資源;如果返回結(jié)果中沒(méi)有 result.data.imgUrl 這個(gè)字段,就用 http://img.smyhvae.com/20160401_01.jpg 作為兜底圖片。這種寫(xiě)法,在實(shí)際開(kāi)發(fā)中經(jīng)常用到。
賦值運(yùn)算符
可以將符號(hào)右側(cè)的值賦值給符號(hào)左側(cè)的變量。
舉例:
-
=直接賦值。比如var a = 5 -
+=。a += 5 等價(jià)于 a = a + 5 -
-=。a -= 5 等價(jià)于 a = a - 5 -
*=。a *= 5 等價(jià)于 a = a * 5 -
/=。a /= 5 等價(jià)于 a = a / 5 -
%=。a %= 5 等價(jià)于 a = a % 5
比較運(yùn)算符
比較運(yùn)算符可以比較兩個(gè)值之間的大小關(guān)系,如果關(guān)系成立它會(huì)返回true,如果關(guān)系不成立則返回false。
比較運(yùn)算符有很多種,比如:
> 大于號(hào)
< 小于號(hào)
>= 大于或等于
<= 小于或等于
== 等于
=== 全等于
!= 不等于
!== 不全等于
比較運(yùn)算符,得到的結(jié)果都是布爾值:要么是true,要么是false。
舉例如下:
var result = 5 > 10; // false
非數(shù)值的比較
(1)對(duì)于非數(shù)值進(jìn)行比較時(shí),會(huì)將其轉(zhuǎn)換為數(shù)字然后再比較。
舉例如下:
console.log(1 > true); //false
console.log(1 >= true); //true
console.log(1 > "0"); //true
//console.log(10 > null); //true
//任何值和NaN做任何比較都是false
console.log(10 <= "hello"); //false
console.log(true > false); //true
(2)特殊情況:如果符號(hào)兩側(cè)的值都是字符串時(shí),不會(huì)將其轉(zhuǎn)換為數(shù)字進(jìn)行比較。比較兩個(gè)字符串時(shí),比較的是字符串的Unicode編碼?!痉浅V匾?,這里是個(gè)大坑,很容易踩到】
比較字符編碼時(shí),是一位一位進(jìn)行比較。如果兩位一樣,則比較下一位。
比如說(shuō),當(dāng)你嘗試去比較"123"和"56"這兩個(gè)字符串時(shí),你會(huì)發(fā)現(xiàn),字符串"56"竟然比字符串"123"要大。也就是說(shuō),下面這樣代碼的打印結(jié)果,其實(shí)是true:(這個(gè)我們一定要注意,在日常開(kāi)發(fā)中,很容易忽視)
// 比較兩個(gè)字符串時(shí),比較的是字符串的字符編碼,所以可能會(huì)得到不可預(yù)期的結(jié)果
console.log("56" > "123"); // true
因此:當(dāng)我們?cè)诒容^兩個(gè)字符串型的數(shù)字時(shí),一定一定要先轉(zhuǎn)型再比較大小,比如 parseInt()。
(3)任何值和NaN做任何比較都是false。
==符號(hào)的強(qiáng)調(diào)
注意==這個(gè)符號(hào),它是判斷是否等于,而不是賦值。
(1)==這個(gè)符號(hào),還可以驗(yàn)證字符串是否相同。例如:
console.log("我愛(ài)你中國(guó)" == "我愛(ài)你中國(guó)"); // 輸出結(jié)果為true
(2)==這個(gè)符號(hào)并不嚴(yán)謹(jǐn),會(huì)做隱式轉(zhuǎn)換,將不同的數(shù)據(jù)類型,轉(zhuǎn)為相同類型進(jìn)行比較(大部分情況下,都是轉(zhuǎn)換為數(shù)字)。例如:
console.log("6" == 6); // 打印結(jié)果:true。這里的字符串"6"會(huì)先轉(zhuǎn)換為數(shù)字6,然后再進(jìn)行比較
console.log(true == "1"); // 打印結(jié)果:true
console.log(0 == -0); // 打印結(jié)果:true
console.log(null == 0); // 打印結(jié)果:false
(3)undefined 衍生自 null,所以這兩個(gè)值做相等判斷時(shí),會(huì)返回true。
console.log(undefined == null); //打印結(jié)果:true。
(4)NaN不和任何值相等,包括他本身。
console.log(NaN == NaN); //false
console.log(NaN === NaN); //false
問(wèn)題:那如果我想判斷 b的值是否為NaN,該怎么辦呢?
答案:可以通過(guò)isNaN()函數(shù)來(lái)判斷一個(gè)值是否是NaN。舉例:
console.log(isNaN(b));
如上方代碼所示,如果 b 為 NaN,則返回true;否則返回false。
===全等符號(hào)的強(qiáng)調(diào)
全等在比較時(shí),不會(huì)做類型轉(zhuǎn)換。如果要保證絕對(duì)等于(完全等于),我們就要用三個(gè)等號(hào)===。例如:
console.log("6" === 6); //false
console.log(6 === 6); //true
上述內(nèi)容分析出:
-
==兩個(gè)等號(hào),不嚴(yán)謹(jǐn),"6"和6是true。 -
===三個(gè)等號(hào),嚴(yán)謹(jǐn),"6"和6是false。
另外還有:==的反面是!=,===的反面是!==。例如:
console.log(3 != 8); //true
console.log(3 != "3"); //false,因?yàn)?=="3"是true,所以反過(guò)來(lái)就是false。
console.log(3 !== "3"); //true,應(yīng)為3==="3"是false,所以反過(guò)來(lái)是true。
三元運(yùn)算符
三元運(yùn)算符也叫條件運(yùn)算符。
語(yǔ)法:
條件表達(dá)式 ? 語(yǔ)句1 : 語(yǔ)句2;
執(zhí)行的流程:
條件運(yùn)算符在執(zhí)行時(shí),首先對(duì)條件表達(dá)式進(jìn)行求值:
- 如果該值為true,則執(zhí)行語(yǔ)句1,并返回執(zhí)行結(jié)果
- 如果該值為false,則執(zhí)行語(yǔ)句2,并返回執(zhí)行結(jié)果
如果條件的表達(dá)式的求值結(jié)果是一個(gè)非布爾值,會(huì)將其轉(zhuǎn)換為布爾值然后再運(yùn)算。
運(yùn)算符的優(yōu)先級(jí)
運(yùn)算符的優(yōu)先級(jí)如下:(優(yōu)先級(jí)從高到低)
-
.、[]、new ()-
++、-- -
!、~、+(單目)、-(單目)、typeof、void、delete -
%、*、/ -
+(雙目)、-(雙目) -
<<、>>、>>> - 關(guān)系運(yùn)算符:
<、<=、>、>= -
==、!==、===、!== &^|&&||?:-
=、+=、-=、*=、/=、%=、<<=、>>=、>>>=、&=、^=、|= ,
注意:邏輯與 && 比邏輯或 || 的優(yōu)先級(jí)更高。
備注:你在實(shí)際寫(xiě)代碼的時(shí)候,如果不清楚哪個(gè)優(yōu)先級(jí)更高,可以把括號(hào)運(yùn)用上。