javascript做為一個指令碼語言,像它的前輩一樣提供了操作資料值的操作符,如算術操作符、位操作符、關係操作符和相等操作符。你可以按照其它常用語言如C、C#等一樣來使用js的操作符,但是遠不如此,它的使用對象不僅限於特定類型,可以對任何類型使用,同時在處理時有著很大的不同。
算術操作符
對數字類型執行++、—、+、-操作不用多說了,js可以對其它任何類型執行這個操作,讓我們看幾個執行個體:
先聲明一些變數,這些變數是這篇文章中的例子都會用到的:
var a = 123; var b = "123"; var c = "123d"; var e = true; var f = false; var g = {}; function h_f() { }; h_f.prototype.valueOf = function () { return 123; }; h_f.prototype.toString = function () { return 456; }; var h = new h_f(); var i_f = function(){}; i_f.prototype.toString = function () { return 123; }; var i = new i_f();
然後執行如下操作:
a++;b++;c++;e++;f++;g++;h++;i++; console.log(a + "|" + b + "|" + c + "|" + e + "|" + f + "|" + g + "|" + h + "|" + i);
在瀏覽器的控制台,可以看到結果:124|124|NaN|2|1|NaN|124|124,這樣我們可以得出一個簡單的結論,js會自動為運算元調用Number()轉換先將運算元轉化為數值,然後再執行操作。Number()轉換的規則,請見javascript應該注意的小case--資料類型。
其實js只是在執行這樣的數值操作如++、—、一元+、一元和二元-、*等時,對運算元執行的Number()的轉換操作,但是對於二元的相加操作+卻不是:如果任何一個值為字串,js會自動為另一個運算元執行toString()的操作,然後執行字串拼接。
布爾操作符(!、&&、||)
其實我們大部分見到它們時候是和邏輯判斷語句一塊的,如if(condition1 && !condition2 || condition3)這樣的語句,在javascript應該注意的小case--資料類型中我們知道js為預設為這樣的語句執行Boolean()的操作,但是我們現在主要討論的是如下面例子的操作。
console.log(!a + "|" + !b + "|" + !c + "|" + !e + "|" + !f + "|" + !g + "|" + !h + "|" + !i);
其中變數還是上個例子的,得到如下結果:false|false|false|false|true|false|false|false,如果這裡我們還可以認為是對操作符執行Boolean()操作之後再執行正常的邏輯非的操作,而對於&&、||卻完全不是這樣了。(通常我們會連用兩個非操作,如!!a來類比Boolean()轉換)
如下面的例子:
console.log(e && a); console.log(f && a); console.log(b && a); console.log(undefined && a); console.log(null && a);
我們得到的結果是123、false、123、undefined、null。有了這樣的結果,我們似乎可以得出其中的規則:第一個運算元的Boolean()轉換為true,就返回第二個運算元,如果為false,返回第一個運算元。其實&&操作是短路操作,只有第一個運算元轉換為true時,才會去處理第二個運算元並返回結果;如果為false,直接返回第一個運算元。
而 || 運算元與 && 相反,只有當第一個運算元轉換的值為false時,才會處理第二個運算元,並返回第二個操作結果。
事實上我們可以看到很多地方的應用,如var obj = otherObj || {};這樣的操作就很好理解了,如果otherObj存在,obj就獲得了引用;如果不存在,相當於一個新對象。總是能保證obj不為null.
關係操作符(>、>=、<、<=)
有了以上的基礎,對於js這樣的操作,可能就有些心理準備,不會那麼突兀了。
規則如下:如果都是數字類型,直接比較;如果都是字串,剛會比較對應位的字元編碼值;如果有一個是數字類型,則把另一個轉換為數實值型別;如果是對象,先調用valueOf方法,如果沒有些方法調用toString方法,再執行以上規則;如果有一個是布爾型 ,則將布爾型先轉為數實值型別再比較。
相等操作符(==、!=、===、!==)
還是先看例子:
console.log(55 == "55");
你能猜測下結果嗎?false??
再看下面的例子:
console.log(55 == "55"); console.log(55 === "55");
或許到這裡,你已經能得猜測出答案了:true、false。
先說全等操作===、!==,這個操作就是比較原始值,不對值進行任何的轉換,這個是如此的確定,因些推薦大家使用全等的操作,避免一些詭異的bug。
再來說==、!=,他們會對運算元執行強制轉換,然後再比較:如果是運算元是布爾值,把true轉為1、false轉為0;如果一個是字串,一個是數字,則將字串轉為數字再比較;如果一個是對象,另一個不是,則調用對象的valueOf之後,再按以上的規則比較。
在進行以上的比較之前,有一些特殊會被執行:null與undefined相等比較返回true;null、undefined不會進行任何的類型轉換;NaN不與任何值相等,甚至是自己;如果兩個都是對象,只有兩個運算元是同一個對象時才相等。
本文並沒有詳細的介紹js所有的操作符,只是就js在操作符上與其它常用語言不一樣的獨特之處列舉一二,瞭解了這些,至少不會讓我們在讀一些開源架構js代碼時一頭霧水,並且可以讓我們的js代碼更簡潔、更安全(少出bug)。