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