JS運(yùn)算符

運(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
  • ()
  • ++、--
  • !~、+(單目)、-(單目)、typeofvoiddelete
  • %、*、/
  • +(雙目)、-(雙目)
  • <<、>>、>>>
  • 關(guān)系運(yùn)算符:<、<=、>>=
  • ==、!==、===!==
  • &
  • ^
  • |
  • &&
  • ||
  • ?:
  • =、+=-=、*=/=、%=<<=、>>=、>>>=、&=、^=、|=
  • ,

注意:邏輯與 && 比邏輯或 || 的優(yōu)先級(jí)更高。

備注:你在實(shí)際寫(xiě)代碼的時(shí)候,如果不清楚哪個(gè)優(yōu)先級(jí)更高,可以把括號(hào)運(yùn)用上。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容