JavaScript高級程序設(shè)計(第3版)學(xué)習(xí)筆記4 js運算符和操作符
1、雖然標(biāo)題是運算符和操作符,然而在我看來并沒有多少嚴(yán)格區(qū)分的必要,在英文中,貌似也是用一個Operator來表示,所以在下文中我可能會混用。甚至,一些不屬于運算符和操作符范疇的,我也整理在這里,只要我覺得必要。
2、對于運算符的優(yōu)先級,你無需一一牢記——我相信你知道最簡單的”先乘除,后加減”,至于其它的,如果你不確定,加上括號好了。在ECMAScript中,優(yōu)先級相同的從左向右運算。
3、對于一些編程語言通用的運算符,比如常用算術(shù)運算符(+-*/),我只會簡單的列舉一下,不會展開,但是請注意,并不是說這些不重要,相反,這些通用運算符甚至處于一個非?;A(chǔ)的地位,只是我覺得你應(yīng)該早已經(jīng)熟悉,沒必要在這里花時間強(qiáng)調(diào)。
4、那么,這里重點關(guān)注什么呢?就是一些在ECMAScript中比較特殊的操作符,或者我認(rèn)為值得花時間強(qiáng)調(diào)的一些地方。
運算符與操作符
類別 | 操作符 | 描述 | 說明 |
一元操作符 | ++ | 自增1 |
1、自增(減)有前置和后置兩種類型,前置先自增(減)再參與其它運算,后置先參與其它運算再自增(減)。 2、在ES中,自增(減)不僅適用于整數(shù),它們可以作用于任意值,對于不是Number類型的值,會先按前一篇文章中的規(guī)則隱式轉(zhuǎn)換為Number,然后再自增(減),此時變量類型也會變成Number類型。 |
-- | 自減1 | ||
+ | 一元加 | 一元加最主要的應(yīng)用就是將操作數(shù)轉(zhuǎn)變?yōu)镹umber類型,相當(dāng)于調(diào)用Number()轉(zhuǎn)換。 | |
- | 一元減 | 一元減則是在一元加的基礎(chǔ)之上再取其相反數(shù)。 | |
算術(shù)操作符 | + | 加 |
1、除了加(+)之外,如果操作數(shù)不是Number類型,會自動調(diào)用Number()轉(zhuǎn)換為Number類型再進(jìn)行計算。 2、對于加減(+-),除了作為算術(shù)運算符。還可以作為一元操作符(見上)。當(dāng)然,由于字符串操作中對加號(+)的重載,還可以用于將任意數(shù)值(的字符串)相連,這也是第1點中為什么要除了加(+),它在含有非Number類型值時,會將所有操作數(shù)轉(zhuǎn)換為字符串相連接。 3、與一般類C語言不同,在ES中,除(/)和取模(%)并不會區(qū)分整數(shù)和浮點數(shù),比如 5 / 2 = 2.5 而不是2,5.3 % 3 = 2.3 而不是2。 4、任意運算,只要操作數(shù)含NaN,結(jié)果就是NaN。但并不是結(jié)果為NaN就一定有一個操作數(shù)為NaN,比如0/0也返回NaN。 5、對于含無窮Infinity的運算,規(guī)定比較多,這里就不列舉了,可以參考原書,或者自行測試。 |
- | 減 | ||
* | 乘 | ||
/ | 除 | ||
% | 取模 | ||
邏輯操作符
(布爾操作符) |
! | 邏輯非 |
首先將操作數(shù)轉(zhuǎn)換為Boolean類型值,然后再取反??梢允褂秒p重非!!將一個數(shù)值轉(zhuǎn)換為相應(yīng)的Boolean值。 |
&& | 邏輯與 |
1、當(dāng)兩個操作數(shù)相應(yīng)的Boolean值均為true時,返回true 2、短路:當(dāng)?shù)谝粋€操作數(shù)相應(yīng)的Boolean值為false時,會直接返回false,不會再計算第二個操作數(shù)。這常常被應(yīng)用在判斷一個變量(屬性)是否有定義,如: | |
|| | 邏輯或 |
1、當(dāng)兩個操作數(shù)相應(yīng)的Boolean值至少有一個為true時,返回true 2、短路:當(dāng)?shù)谝粋€操作數(shù)相應(yīng)的Boolean值為true時,會直接返回true,不會再計算第二個操作數(shù)。 3、邏輯或,除了用于一般的判斷之外,還常常被應(yīng)用在提供默認(rèn)值的情況,如: function Fn(obj){obj = obj || {}; } 這里如果調(diào)用Fn未傳入obj,則會自動給obj賦值為undefined,然后因為undefined的相應(yīng)Boolean值為false,所以會將一個空對象{}賦值給obj,如果調(diào)用傳入了obj,則因為任意對象的Boolean值為true,所以就不會取后面的{},從而達(dá)到給obj一個默認(rèn)值{}的效果。 這種方式還被應(yīng)用在大型JS庫的多個相對獨立的文件中: //file2
| |
關(guān)系操作符 (比較操作符) |
< | 小于 |
1、只要有一個操作數(shù)是Number類型或Boolean類型值,就將兩個操作數(shù)轉(zhuǎn)換成Number類型值(如果需要轉(zhuǎn)換)執(zhí)行數(shù)值比較。 2、字符串比較,會逐個比較字符編碼值。 3、操作符是對象時,調(diào)用valueOf()(如果沒有,就調(diào)用toString()),再將結(jié)果按上面規(guī)則比較。 4、任意數(shù)和NaN比較返回false。 |
<= | 小于或等于 | ||
> | 大于 | ||
>= | 大于或等于 | ||
== | 相等 |
1、相等和不等(==、!=)在比較時,只要有必要,就會隱式類型轉(zhuǎn)換。 2、全等和不全等(===、!==)在比較時,不會轉(zhuǎn)換類型,如果類型不一致,直接為!==。 3、結(jié)合1、2,可以知道,a===b則一定有a==b,而a!=b則一定有a!==b。 | |
!= | 不等 | ||
=== | 全等 | ||
!== | 不全等 | ||
賦值操作符 | = | 賦值 | |
復(fù)合算術(shù)賦值操作符 | 算術(shù)運算符加= | 對應(yīng)算術(shù)運算符,有+=、-=、*=、/=、%= | |
復(fù)合按位賦值操作符 | 按位運算符加= | 對應(yīng)按位運算符,有~=、&=、|=、^=、<<=、>>=、>>>= | |
按位操作符 | ~ | 按位非 | 按位取反,也即返回反碼 |
& | 按位與 | 按位對齊,逐位操作,只有兩個操作位均為1才返回1,否則該位返回0,最后將所有位操作結(jié)果組合返回 | |
| | 按位或 | 按位對齊,逐位操作,只有兩個操作位均為0才返回0,否則該位返回1,最后將所有位操作結(jié)果組合返回 | |
^ | 按位異或 | 按位對齊,逐位操作,兩個操作位不相同時返回1,否則該位返回0,最后將所有位操作結(jié)果組合返回 | |
<< | 左移 | 二進(jìn)制數(shù)向左移位,左移不會改變符號位 | |
>> | 有符號右移 | 二進(jìn)制數(shù)向右移位,高位以符合位填充 | |
>>> | 無符號右移 | 二進(jìn)制數(shù)向右移位,直接右移,對于正數(shù),結(jié)果和>>相同,對于負(fù)數(shù),會把負(fù)數(shù)的二進(jìn)制補(bǔ)碼當(dāng)成正數(shù)的二進(jìn)制碼處理 | |
字符串操作符 | + | 字符串連接 | 相當(dāng)于concat()函數(shù),會先將所有操作數(shù)轉(zhuǎn)換為字符串,然后再連接。注意,字符串一旦創(chuàng)建就不會變更,執(zhí)行字符串連接時,在后臺會有一個中間的連接和銷毀過程,這也是老舊瀏覽器在大量字符串連接操作時運行緩慢的原因。 |
+= | 字符串連接復(fù)合 | a+=b,相當(dāng)于a=a+b。 | |
對象操作符 | . | 屬性訪問符 | 簡單的對象屬性訪問符。 |
[] | 屬性或(類)數(shù)組訪問 | 通過[],可以訪問名稱是一個變量或含有特殊字符的屬性。 | |
new | 調(diào)用構(gòu)造函數(shù)創(chuàng)建對象 | 返回一個新創(chuàng)建的對象,在構(gòu)造函數(shù)內(nèi)部的this被指向這個新創(chuàng)建的對象。 | |
delete | 變量、屬性刪除 | 刪除屬性(變量可以看成是全局對象或執(zhí)行環(huán)境的一個屬性)。 | |
void | 返回undefined。 | ||
in | 判斷屬性 | 對象屬性或原型鏈上的屬性。 | |
instanceof | 原型判斷 | 比較同一個上下文中的對象是否為另一個對象的原型。 | |
其它操作符 | ?: | 條件操作符 | 語法;var value = exp ? trueExp : falseExp。 相當(dāng)于var value; if(exp){ value = trueExp;}else{value = falseExp;} |
, | 逗號操作符 | 主要用于聲明多個變量,這也是很多JS庫的流行做法。例如:var num1=1,num2=2,num3=3; | |
() | 分組操作符 |
主要用途: 1、結(jié)合逗號操作符用于賦值。例如:var num = (5,1,4,8,0);這里num最后的值為0。 2、轉(zhuǎn)換為表達(dá)式。比如eval('('+jsStr+')');又比如: | |
typeof | 類型操作符 |
返回一個字符串值:Undefined類型—>'undefined'、Null類型—>'object'、Boolean類型—>'boolean'、Number類型—>‘number'、String—>'string'、內(nèi)置Function對象的實例—>'function'、其它Object類型—>'object'。(有些瀏覽器實現(xiàn)略有不同) |
說明幾點:
1、這里的分類并不十分嚴(yán)格,比如按位非(~)、邏輯非(!)、delete、void、typeof,都可以算是一元操作符,而自增(++)在很多資料中也被歸為算術(shù)操作符之中。我在整理時則主要參考原書分類,也兼顧自然性。
2、加號(+)的用法比較靈活,需注意,特別是用于計算時,忽略了其中的字符串,會很容易犯錯誤。
3、typeof一般用來判斷簡單數(shù)據(jù)類型,如果是對象類型,因為大部分返回的都是object,沒有多大實際用處,而instanceof的判斷也需要滿足同一個上下文的條件,否則也會出錯,對于對象類別的判斷會在后面講述對象時再詳細(xì)說明另外一種更為穩(wěn)妥的方法。
4、先看下面的代碼:
var numVal = 10.00,
strVal = '10',
strObj = new String('10');
console.info(numVal == strVal);//true
console.info(typeof (strVal+strObj));//string
第一個輸出的竟然是true,是不是出乎你的意料?在這里,由于==比較符發(fā)生了隱式類型轉(zhuǎn)換,會將Number類型轉(zhuǎn)換為String類型,然后Number類型的10.00因為小數(shù)點后沒有不是0的數(shù)值,會被解析成整數(shù)10,從而比較的時候會相等。第二個輸出是string,這其實還是比較容易理解的,strVal是字符串,strObj是字符串對象,兩者相加,會把對象轉(zhuǎn)換成字符串,所以最終結(jié)果也是字符串類型。
5、關(guān)于符號,重復(fù)一下幾個流行的用法(這里不涉及正則表達(dá)式中的用法):
(1)使用一元加號(+)轉(zhuǎn)換為Number類型。
(2)使用雙重邏輯非(!!)轉(zhuǎn)換為Boolean類型。
(3)使用邏輯與(&&)來檢測對象是否存在并進(jìn)行后續(xù)操作。
(4)使用邏輯或(||)來給函數(shù)參數(shù)提供默認(rèn)值。
(5)使用分組(())來明確指定為表達(dá)式。
(6)使用花括號({})來定義對象字面量,JSON數(shù)據(jù)格式,代碼塊。
(7)使用中括號([])來定義數(shù)組字面量,JSON數(shù)據(jù)格式,訪問數(shù)組,訪問名稱是變量或特殊字符的屬性。
6、關(guān)于按位運算,雖然結(jié)果不是很直觀,但是運行效率高,也有很多有趣的應(yīng)用,比如不使用中間變量直接交換兩個數(shù)值、判斷奇數(shù)和偶數(shù)、MD5加密等等,有興趣的朋友可以找相關(guān)資料自行研究。
相關(guān)文章
簡述JavaScript對傳統(tǒng)文檔對象模型的支持
這篇文章主要介紹了簡述JavaScript對傳統(tǒng)文檔對象模型的支持,是JS學(xué)習(xí)進(jìn)階中的重要知識,需要的朋友可以參考下2015-06-06Javascript Object 對象學(xué)習(xí)筆記
這篇文章主要介紹了Javascript Object 對象學(xué)習(xí)筆記,需要的朋友可以參考下2014-12-12JavaScript 學(xué)習(xí)筆記(十四) 正則表達(dá)式
RegExp類 RegExp對象的構(gòu)造函數(shù)可以帶一個或兩個參數(shù) 第一個參數(shù)是描述需要進(jìn)行匹配的模式字符串,如果還有第二個參數(shù),這個參數(shù)則制定了額外的處理指令。2010-01-01Javascript入門學(xué)習(xí)第五篇 js函數(shù)
上篇文章講了js中對象和數(shù)組的一些方法。 這章我們先說說函數(shù),然后來點實戰(zhàn)。2008-07-07JavaScript創(chuàng)建、讀取和刪除cookie
通過本文你將粗略的明白cookie是什么,如何通過js創(chuàng)建/存儲以及獲取cookie,如何讓cookie過期來刪除cookie2019-09-09