2020-04-21

javascript共提供10個算術(shù)運算符

.加法運算符:x + y
減法運算符:x - y
乘法運算符:x * y
除法運算符:x / y
指數(shù)運算符:x ** y
余數(shù)運算符:x % y
自增運算符:++x或者x++
自減運算符:--x或者x--
數(shù)值運算符:+x
負數(shù)值運算符:-x
JavaScript允許非數(shù)值的相加。
true+true //2
1+true //2
上面代碼中的這兩種情況,布爾值都會自動轉(zhuǎn)成數(shù)值,然后再相加。

比較特殊的是,如果是兩個字符串相加,這時加法運算符會變成連接運算符,返回一個新的字符串,將兩個原字符串連接在一起。


image.png

如果一個運算子是字符串,另一個運算子是非字符串,這時非字符串會轉(zhuǎn)成字符串,再連接在一起。


image.png

加法運算符是在運行時決定,到底是執(zhí)行相加,還是執(zhí)行連接。也就是說,運算子的不同,導(dǎo)致了不同的語法行為,這種現(xiàn)象稱為“重載”(overload)。由于加法運算符存在重載,可能執(zhí)行兩種運算,使用的時候必須很小心。
image.png

上面代碼中,由于從左到右的運算次序,字符串的位置不同會導(dǎo)致不同的結(jié)果。

除了加法運算符,其他算術(shù)運算符(比如減法、除法和乘法)都不會發(fā)生重載。它們的規(guī)則是:所有運算子一律轉(zhuǎn)為數(shù)值,再進行相應(yīng)的數(shù)學(xué)運算。


image.png

對象的相加

如果運算子是對象,必須先轉(zhuǎn)成原始類型的值,然后再相加。


image.png

上面代碼中,對象obj轉(zhuǎn)成原始類型的值是[object Object],再加2就得到了上面的結(jié)果。

對象轉(zhuǎn)成原始類型的值,規(guī)則如下。
首先,自動調(diào)用對象的valueOf方法。


image.png

一般來說,對象的valueOf方法總是返回對象自身,這時再自動調(diào)用對象的toString方法,將其轉(zhuǎn)為字符串。


image.png

對象的toString方法默認返回[object Object]。
知道了這個規(guī)則以后,就可以自己定義valueOf方法或toString方法,得到想要的結(jié)果。
image.png

這個例子中,由于valueOf方法直接返回一個原始類型的值,所以不再調(diào)用toString方法。
下面是自定義toString方法的例子。

image.png

這里有一個特例,如果運算子是一個Date對象的實例,那么會優(yōu)先執(zhí)行toString方法


image.png

余數(shù)運算符

余數(shù)運算符(%)返回前一個運算子被后一個運算子除,所得的余數(shù)。
image.png

需要注意的是,運算結(jié)果的正負號由第一個運算子的正負號決定。


image.png

所以,為了得到負數(shù)的正確余數(shù)值,可以先使用絕對值函數(shù)。Math.abs()
image.png

余數(shù)運算符還可以用于浮點數(shù)的運算。但是,由于浮點數(shù)不是精確的值,無法得到完全準確的結(jié)果。


image.png

自增和自減運算符

自增和自減運算符,是一元運算符,只需要一個運算子。它們的作用是將運算子首先轉(zhuǎn)為數(shù)值,然后加上1或者減去1。它們會修改原始變量。


image.png

上面代碼的變量x自增后,返回2,再進行自減,返回1。這兩種情況都會使得,原始變量x的值發(fā)生改變。

運算之后,變量的值發(fā)生變化,這種效應(yīng)叫做運算的副作用。自增和自減運算符是僅有的兩個具有副作用的運算符,其他運算符都不會改變變量的值。
自增和自減運算符有一個需要注意的地方,就是放在變量之后,會先返回變量操作前的值,再進行自增/自減操作;放在變量之前,會先進行自增/自減操作,再返回變量操作后的值。


image.png

上面代碼中,x是先返回當(dāng)前值,然后自增,所以得到1;y是先自增,然后返回新的值,所以得到2。

數(shù)值運算符,負數(shù)值運算符

數(shù)值運算符(+)同樣使用加號,但它是一元運算符(只需要一個操作數(shù)),而加法運算符是二元運算符(需要兩個操作數(shù))。
數(shù)值運算符的作用在于可以將任何值轉(zhuǎn)為數(shù)值(與Number函數(shù)的作用相同)


image.png

上面代碼表示,非數(shù)值經(jīng)過數(shù)值運算符以后,都變成了數(shù)值(最后一行NaN也是數(shù)值)。

負數(shù)值運算符(-),也同樣具有將一個值轉(zhuǎn)為數(shù)值的功能,只不過得到的值正負相反。連用兩個負數(shù)值運算符,等同于數(shù)值運算符。


image.png

上面代碼最后一行的圓括號不可少,否則會變成自減運算符。
數(shù)值運算符號和負數(shù)值運算符,都會返回一個新的值,而不會改變原始變量的值。

賦值運算符

賦值運算符用于給變量賦值。

最常見的賦值運算符,當(dāng)然就是等號(=)。
image.png

賦值運算符還可以與其他運算符結(jié)合,形成變體。下面是與算術(shù)運算符的結(jié)合。
image.png

比較運算符

比較運算符用于比較兩個值的大小,然后返回一個布爾值,表示是否滿足指定的條件。

JavaScript 一共提供了8個比較運算符。
image.png

非相等運算符:字符串的比較

image.png

image.png

非相等運算符:非字符串的比較

如果兩個運算子之中,至少有一個不是字符串,需要分成以下兩種情況。

1.原始類型值

如果兩個運算子都是原始類型的值,則是先轉(zhuǎn)成數(shù)值再比較。


image.png

這里需要注意與NaN的比較。任何值(包括NaN本身)與NaN比較,返回的都是false。(#任何值和NaN比都返回NaN)


image.png

2.對象

運算子是對象,會轉(zhuǎn)為原始類型的值,再進行比較。
對象轉(zhuǎn)換成原始類型的值,算法是先調(diào)用valueOf方法;如果返回的還是對象,再接著調(diào)用toString方法。


image.png

嚴格相等運算符

JavaScript 提供兩種相等運算符:==和===。

簡單說,它們的區(qū)別是相等運算符(==)比較兩個值是否相等,嚴格相等運算符(===)比較它們是否為“同一個值”。如果兩個值不是同一類型,嚴格相等運算符(===)直接返回false,而相等運算符(==)會將它們轉(zhuǎn)換成同一個類型,再用嚴格相等運算符進行比較。

1.不同類型的值

如果兩個值的類型不同,直接返回false。
image.png

2.同一類的原始類型值

image.png

上面代碼比較十進制的1與十六進制的1,因為類型和值都相同,返回true。
需要注意的是,NaN與任何值都不相等(包括自身)。另外,正0等于負0。


image.png

3.復(fù)合類型值

兩個復(fù)合類型(對象、數(shù)組、函數(shù))的數(shù)據(jù)比較時,不是比較它們的值是否相等,而是比較它們是否指向同一個地址。


image.png

上面代碼分別比較兩個空對象、兩個空數(shù)組、兩個空函數(shù),結(jié)果都是不相等。原因是對于復(fù)合類型的值,嚴格相等運算比較的是,它們是否引用同一個內(nèi)存地址,而運算符兩邊的空對象、空數(shù)組、空函數(shù)的值,都存放在不同的內(nèi)存地址,結(jié)果當(dāng)然是false。

如果兩個變量引用同一
image.png

注意,對于兩個對象的比較,嚴格相等運算符比較的是地址,而大于或小于運算符比較的是值。
image.png

4.undefined 和 null

undefined和null與自身嚴格相等
image.png

由于變量聲明后默認值是undefined,因此兩個只聲明未賦值的變量是相等的。
image.png

嚴格不相等運算符

嚴格相等運算符有一個對應(yīng)的“嚴格不相等運算符”(!==),它的算法就是先求嚴格相等運算符的結(jié)果,然后返回相反值。


image.png

上面代碼中,感嘆號!是求出后面表達式的相反值。

相等運算符

相等運算符用來比較相同類型的數(shù)據(jù)時,與嚴格相等運算符完全一樣。
image.png

比較不同類型的數(shù)據(jù)時,相等運算符會先將數(shù)據(jù)進行類型轉(zhuǎn)換,然后再用嚴格相等運算符比較。下面分成四種情況,討論不同類型的值互相比較的規(guī)則。

1.原始類型值

原始類型的值會轉(zhuǎn)換成數(shù)值再進行比較。


image.png

2.對象與原始類型值比較

對象(這里指廣義的對象,包括數(shù)組和函數(shù))與原始類型的值比較時,對象轉(zhuǎn)換成原始類型的值,再進行比較。
image.png

面代碼中,數(shù)組[1]與數(shù)值進行比較,會先轉(zhuǎn)成數(shù)值,再進行比較;與字符串進行比較,會先轉(zhuǎn)成字符串,再進行比較;與布爾值進行比較,對象和布爾值都會先轉(zhuǎn)成數(shù)值,再進行比較。

3.undefined 和 null

undefined和null與其他類型的值比較時,結(jié)果都為false,它們互相比較時結(jié)果為true。

image.png

4.相等運算符的缺點

相等運算符隱藏的類型轉(zhuǎn)換,會帶來一些違反直覺的結(jié)果。
image.png

上面這些表達式都不同于直覺,很容易出錯。因此建議不要使用相等運算符(==),最好只使用嚴格相等運算符(===)。

不相等運算符

相等運算符有一個對應(yīng)的“不相等運算符”(!=),它的算法就是先求相等運算符的結(jié)果,然后返回相反值。


image.png

布爾運算符

概述

布爾運算符用于將表達式轉(zhuǎn)為布爾值,一共包含四個運算符。

取反運算符:!
且運算符:&&
或運算符:||
三元運算符:?:

取反運算符(!)

取反運算符是一個感嘆號,用于將布爾值變?yōu)橄喾粗?,即true變成false,false變成true。

對于非布爾值,取反運算符會將其轉(zhuǎn)為布爾值??梢赃@樣記憶,以下六個值取反后為true,其他值都為false。


image.png

且運算符(&&)

且運算符(&&)往往用于多個表達式的求值。
它的運算規(guī)則是:如果第一個運算子的布爾值為true,則返回第二個運算子的值(注意是值,不是布爾值);如果第一個運算子的布爾值為false,則直接返回第一個運算子的值,且不再對第二個運算子求值。


image.png

上面代碼的最后一個例子,由于且運算符的第一個運算子的布爾值為false,則直接返回它的值0,而不再對第二個運算子求值,所以變量x的值沒變。

這種跳過第二個運算子的機制,被稱為“短路”。有些程序員喜歡用它取代if結(jié)構(gòu),比如下面是一段if結(jié)構(gòu)的代碼,就可以用且運算符改寫。
image.png

且運算符可以多個連用,這時返回第一個布爾值為false的表達式的值。如果所有表達式的布爾值都為true,則返回最后一個表達式的值。
image.png

或運算符(||)

或運算符(||)也用于多個表達式的求值。它的運算規(guī)則是:如果第一個運算子的布爾值為true,則返回第一個運算子的值,且不再對第二個運算子求值;如果第一個運算子的布爾值為false,則返回第二個運算子的值。
image.png

短路規(guī)則對這個運算符也適用。
image.png

上面代碼中,或運算符的第一個運算子為true,所以直接返回true,不再運行第二個運算子。所以,x的值沒有改變。這種只通過第一個表達式的值,控制是否運行第二個表達式的機制,就稱為“短路”。

或運算符可以多個連用,這時返回第一個布爾值為true的表達式的值。如果所有表達式都為false,則返回最后一個表達式的值。


image.png

或運算符常用于為一個變量設(shè)置默認值。
image.png

上面代碼表示,如果函數(shù)調(diào)用時,沒有提供參數(shù),則該參數(shù)默認設(shè)置為空字符串。

三元條件運算符(?:)

三元條件運算符由問號(?)和冒號(:)組成,分隔三個表達式。它是JavaScript語言唯一一個需要三個運算子的運算符。如果第一個表達式的布爾值為true,則返回第二個表達式的值,否則返回第三個表達式的值。


image.png

通常來說,三元條件表達式與if...else語句具有同樣表達效果,前者可以表達的,后者也能表達。但是兩者具有一個重大差別,if...else是語句,沒有返回值;三元條件表達式是表達式,具有返回值。所以,在需要返回值的場合,只能使用三元條件表達式,而不能使用if..else。


image.png

上面代碼中,console.log方法的參數(shù)必須是一個表達式,這時就只能使用三元條件表達式。如果要用if...else語句,就必須改變整個代碼寫法了。

其他運算符,運算順序

void 運算符

void運算符的作用是執(zhí)行一個表達式,然后不返回任何值,或者說返回undefined。
image.png

上面是void運算符的兩種寫法,都正確。建議采用后一種形式,即總是使用圓括號。因為void運算符的優(yōu)先性很高,如果不使用括號,容易造成錯誤的結(jié)果。比如,void 4 + 7實際上等同于(void 4) + 7。

下面是void運算符的一個例子。
image.png

這個運算符的主要用途是瀏覽器的書簽工具,以及在超級鏈接中插入代碼防止網(wǎng)頁跳轉(zhuǎn)。
image.png
面代碼中,點擊鏈接后,會先執(zhí)行onclick的代碼,由于onclick返回false,所以瀏覽器不會跳轉(zhuǎn)到example.com。

void運算符可以取代上面的寫法。
image.png

下面是一個更實際的例子,用戶點擊鏈接提交表單,但是不產(chǎn)生頁面跳轉(zhuǎn)。
image.png

逗號運算符

逗號運算符用于對兩個表達式求值,并返回后一個表達式的值。
image.png

逗號運算符的一個用途是,在返回一個值之前,進行一些輔助操作
image.png

運算順序

優(yōu)先級

JavaScript各種運算符的優(yōu)先級別是不一樣的。優(yōu)先級高的運算符先執(zhí)行,優(yōu)先級低的運算符后執(zhí)行。
image.png

上面的代碼中,乘法運算符(*)的優(yōu)先性高于加法運算符(+),所以先執(zhí)行乘法,再執(zhí)行加法,相當(dāng)于下面這樣。

如果多個運算符混寫在一起,常常會導(dǎo)致令人困惑的代碼。
image.png

image.png

圓括號的作用

圓括號(())可以用來提高運算的優(yōu)先級,因為它的優(yōu)先級是最高的,即圓括號中的表達式會第一個運算。
image.png

運算符的優(yōu)先級別十分繁雜,且都是硬性規(guī)定,因此建議總是使用圓括號,保證運算順序清晰可讀,這對代碼的維護和除錯至關(guān)重要。

順便說一下,圓括號不是運算符,而是一種語法結(jié)構(gòu)。它一共有兩種用法:一種是把表達式放在圓括號之中,提升運算的優(yōu)先級;另一種是跟在函數(shù)的后面,作用是調(diào)用函數(shù)。

注意,因為圓括號不是運算符,所以不具有求值作用,只改變運算的優(yōu)先級。


image.png

上面代碼的第二行,如果圓括號具有求值作用,那么就會變成1 = 2,這是會報錯了。但是,上面的代碼可以運行,這驗證了圓括號只改變優(yōu)先級,不會求值。
這也意味著,如果整個表達式都放在圓括號之中,那么不會有任何效果。

函數(shù)放在圓括號中,會返回函數(shù)本身。如果圓括號緊跟在函數(shù)的后面,就表示調(diào)用函數(shù)。

image.png

圓括號之中,只能放置表達式,如果將語句放在圓括號之中,就會報錯。


image.png

左結(jié)合與右結(jié)合

對于優(yōu)先級別相同的運算符,大多數(shù)情況,計算順序總是從左到右,這叫做運算符的“左結(jié)合”,即從左邊開始計算。

image.png

上面代碼先計算最左邊的x與y的和,然后再計算與z的和。
是少數(shù)運算符的計算順序是從右到左,即從右邊開始計算,這叫做運算符的“右結(jié)合”。其中,最主要的是賦值運算符(=)和三元條件運算符(?:)。
image.png

上面代碼的運算結(jié)果,相當(dāng)于下面的樣子。
image.png

指數(shù)運算符(**)也是右結(jié)合的。
image.png

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

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

  • 運算符是處理數(shù)據(jù)的基本方法,用來從現(xiàn)有的值得到新的值。JavaScript 提供了多種運算符,本章逐一介紹這些運算...
    徵羽kid閱讀 778評論 0 0
  • 算術(shù)運算符 JavaScript 共提供10個算術(shù)運算符,用來完成基本的算術(shù)運算。 加法運算符:x + y 減法運...
    guyigg閱讀 1,377評論 0 1
  • 標簽: 我的筆記 ---學(xué)習(xí)資料:http://javascript.ruanyifeng.com/ 1. 導(dǎo)論 ...
    暗夜的怒吼閱讀 940評論 0 1
  • 第5章 引用類型(返回首頁) 本章內(nèi)容 使用對象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學(xué)一百閱讀 3,676評論 0 4
  • 這是16年5月份編輯的一份比較雜亂適合自己觀看的學(xué)習(xí)記錄文檔,今天18年5月份再次想寫文章,發(fā)現(xiàn)簡書還為我保存起的...
    Jenaral閱讀 3,142評論 2 9

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