- 記下一些關於運算符的小技巧或容易出錯的地方
%運算符
取余運算符運算結果的正負號由第一個運算子的正負號決定,比如:
1 -1 % 2 // -1 2 1 % -2 // 1
所以有時候對負數取余會出現錯誤,使用絕對值函數可以避免錯誤:
// 會出錯 function isOdd(n) { return n % 2 === 1; } isOdd(-5) // false isOdd(-4) // false // 正確了 function isOdd(n) { return Math.abs(n % 2) === 1; } isOdd(-5) // true isOdd(-4) // false
+運算符
+運算符與其他運算符不太一樣,我們知道它可以用來連接字符串操作,是因為用+運算符的時候它通常會將其他類型的值轉為字符串,但是除了它比如說-運算符等都會將其他類型的值轉換為數值,像這樣:
var now = new Date(); typeof (now + 1) // "string" typeof (now - 1) // "number"
當運算子中出現對象的時候:
1 + [1,2] // "11,2" 1 + {a:1} // "1[object Object]"
則先調用該對象的valueOf方法。如果返回結果為原始類型的值,則轉換為字符串;否則繼續調用該對象的toString方法,然后轉換為字符串。
但是:
{a:1} + 1 // 1 ({a:1})+1 "[object Object]1"
這是為什么呢?此時{a:1}被當做了代碼塊處理,而這個代碼塊沒有返回值,所以整個表達式就返回1了。但是放在了圓括號中的{a:1},因為js預期()中是一個值,所以它就又被當做對象處理了。
**特殊表達式:**
1. 空數組+空數組
先調用valueOf()返回空數組本身,再調用toString(),返回空字符串。
[] + [] // ""
2. 空數組+空對象
[]得到'',{}得到"[object Object]"
[] + {} // "[object Object]"
3. 空對象+空數組
{}被視作代碼塊省略,+[]就是將[]轉換為數值的意思了得到0.
{} + [] // 0
4. 空對象+空對象
同樣{}被當做代碼塊省略了,+{}轉數值得到NaN
{} + {} // NaN
如果第一個空對象不被當做空代碼塊的話:
({}) + {} // "[object Object][object Object]" ({} + {}) // "[object Object][object Object]" console.log({} + {}) // "[object Object][object Object]" var a = {} + {}; a // "[object Object][object Object]"
此外,當+運算符作為數值運算符放在其他值前面的時候,可以用於將任何值轉為數值,就像Number函數那樣:
+true // 1 +[] // 0 +{} // NaN
!取反運算符
!取反運算符連續對同一個值進行取反運算等於將其轉換為對應的布爾值,就像Boolean函數那樣:
!!x // 等同於 Boolean(x)
此外,如果我們想排除null這個對象,可以這樣寫:
if(!!x){ //do something! }
這是因為:!!null 值是 false,其他的 object !!obj 值都是 true。
~否運算符
~運算符是根據值的二進制二進制形式進行運算的。
~ 3 // -4
它的運算原理就是根據數值的32位二進制整數形式運算,補碼存儲的原理如果是負數,需要將取反后的值減一再取反然后加上負號。
比較麻煩,但是我們可以記成一個值與它取反后的值相加等於-1.
~~2.9 // 2
兩次否運算能夠對小數取整,並且這是取整方法中最快的一種。
^異或運算符
兩次異或運算交換兩個數的值:
var a = 10; var b = 99; a^=b, b^=a, a^=b; a // 99 b // 10
<< 左移運算符
左移0位可用於取整:
13.5 << 0 // 13 -13.5 << 0 // -13
左移運算可以將顏色的RGB值轉為HEX值:
var color = {r: 186, g: 218, b: 85}; // RGB to HEX var rgb2hex = function(r, g, b) { return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).substr(1); } rgb2hex(color.r,color.g,color.b) // "#bada55"
>> 右移運算
右移運算可以模擬2的整除運算:
5 >> 1 // 相當於 5 / 2 = 2 21 >> 2 // 相當於 21 / 4 = 5 21 >> 3 // 相當於 21 / 8 = 2 21 >> 4 // 相當於 21 / 16 = 1
此外,void運算符的作用是用來執行一個表達式,然后返回undefined,而且它的運算符優先級也比較高void 4+7 實際上等同於 (void 4) +7。一般運算符是左結合的,但是=和三目運算符?:卻是右結合的:
w = x = y = z; q = a?b:c?d:e?f:g;
//相當於: w = (x = (y = z)); q = a?b:(c?d:(e?f:g));