JavaScript 操做符(一)

一元操做符

只能操做一個值的操做符叫作一元操做符。是ECMAScript中最簡單的操做符。函數

遞增和遞減操做符

  • 執行前置遞增遞減操做時,變量的值是在語句被求值以前改變的。(在計算機科學領域,這種狀況一般被稱爲副效應).
  • 執行後置遞增遞減操做時,變量的值是在語句被求值以後改變的。
  • 當一條語句只有遞增或遞減操做時,前置和後置沒有區別。
let num1 = 1;
++num1;
console.log(num1); // 2

let num2 = 1;
num2++;
console.log(num1); // 2

let num3 = 1;
console.log(++num3); // 2

let num4 = 1;
console.log(num4++); // 1

let num5 = 2;
let num6 = 20;
let num7 = --num5 + num6; // 21
let num8 = num5 + num6; // 21 上面的語句改變了num5的值

let num9 = 2;
let num10 = 20;
let num11 = num9-- + num10; // 22
let num12 = num9 + num10; // 21 上面的語句改變了num5的值

除了適用於整數,還有能夠用於字符串、布爾值、浮點數值、對象。最終都變爲數值變量。設計

  • String:包含有效數字字符則先轉爲數值,再執行加減1;不包含有效數字字符則將變量值設置爲NaN。
  • Boolean:將 true(false) 轉爲 1(0),再執行加減1。
  • Object: 先調用 valueOf() 得到一個可供操做的值,而後對該值應用前述規則。若是結果是NaN,則調用 toString() 後再應用前述規則。
let s1 = "2", s2 = "str";
let b1 = true, b2 = false;
let f = 1.1;
let o1 = {
  valueOf() {
    return 10;
  }
}
let o2 = {
  valueOf() {
    return NaN;
  }
}
console.log(++s1); // 3
console.log(++s2); // NaN
console.log(++b1); // 2
console.log(++b2); // 1
console.log(--f); // 0.10000000000000009 (因爲浮點舍入錯誤所致)
console.log(--o1); // 9
console.log(--o2); // NaN

一元加和減操做符

在變量前使用一元操做符:

  • Number: 不變
  • String:包含有效數字字符則先轉爲數值;不包含有效數字字符則將變量值設置爲NaN。
  • Boolean:將 true(false) 轉爲 1(0)。
  • Object: 先調用 valueOf() 和(或)toString() 方法,再轉換獲得的值。
let n = 1;
let s1 = "10", s2 = "10a", s3 = "a10", s4 = "a";
let b1 = true, b2 = false;
let f = 1.1;
let o1 = {
  valueOf(){
    return 10;
  }
}, o2 = {
  valueOf(){
    return NaN;
  }
}

console.log(+n); // 1

console.log(+s1); // 10
console.log(+s2); // NaN
console.log(+s3); // NaN
console.log(+s4); // NaN

console.log(+b1); // 1
console.log(+b2); // 0
console.log(+f); // 1.1
console.log(+o1); // 10
console.log(+o2); // NaN

在變量前使用一元操做符:

遵循一元加操做符規則,最後將獲得的數值轉換爲負數。code

位操做符

  • 位操做符是按內存中表示數值的位來操做數值。速度快。
  • 位操做符就是先將64位的值轉換成32位的整數,而後執行操做,再將結果轉換爲64位。ECMAScript中的數值都是以IEEE-754 64位格式存儲。
  • 位操做符對 NaNInfinity 當作 0 來處理。
  • 對於非數值,會先使用 Number() 函數將該值轉換爲一個數值(自動完後),再執行操做,最終獲得一個數值。
  • 在處理有符號的整數時,是不能訪問位31的。

對於有符號的整數,32位中的前31位用於表示整數的值。第32位用於表示數值的符號:0表示整數,1表示負數。這個表示符號的位叫作符號位,它的值決定了其餘位數值的格式。默認狀況下,ECMAScript 中的全部整數都是有符號整數,不過也存在無符號整數。對於無符號整數,第32位再也不表示符號,那麼它能表示的值天然能夠更大。對象

正數以純二進制格式存儲:ip

例如數值18的二進制:00000000000000000000000000010010內存

負數以二進制補碼的格式存儲:字符串

二進制補碼計算方式:get

  1. 求這個數值絕對值的二進制碼。
  2. 求二進制反碼。0替換爲1,1替換爲0。
  3. 獲得的二進制反碼加1。

獲取 -18 的二進制碼:it

  1. 首先求得 18 的二進制碼即:
    0000 0000 0000 0000 0000 0000 0001 0010
  2. 求二進制反碼:
    1111 1111 1111 1111 1111 1111 1110 1101
  3. 將二進制反碼加1:
    1111 1111 1111 1111 1111 1111 1110 1110

ECMAScript會盡力向咱們隱藏全部上面的這些操做,以更合乎邏輯的形式展示出來console

const num = -18;
num.toString(2); // "-10010"

按位非(NOT)

由符號 ~ 表示,返回數值的反碼。本質就是操做數的負值減1。

const n1 = 25; //  二進制 00000000000000000000000000011001
const n2 = ~n1; // 二進制 11111111111111111111111111100110
console.log(n2); // -26   這裏也解釋了爲何計算二進制補碼的第3步要加1。

按位與(AND)

由符號 & 表示。兩個數值對應位都是1才返回1,不然返回0

const result = 25 & 3;
console.log(result); // 1

// 二進制:
//  25 = 00000000000000000000000000011001
//   3 = 00000000000000000000000000000011
// AND = 00000000000000000000000000000001

按位或(OR)

由符號 | 表示。兩個數值對應位有一個1就返回1,不然返回0

const result = 25 | 3;
console.log(result); // 27

// 二進制:
//  25 = 00000000000000000000000000011001
//   3 = 00000000000000000000000000000011
//  OR = 00000000000000000000000000011011

按位異或(XOR)

由符號 ^ 表示。兩個數值對應位只有一個1才返回1,不然返回0

const result = 25 ^ 3;
console.log(result); // 26

// 二進制:
//  25 = 00000000000000000000000000011001
//   3 = 00000000000000000000000000000011
//  OR = 00000000000000000000000000011010

左移

由符號 << 表示。將數值的全部位向左移動指定位數。

左移不會影響操做數的符號位。例如:將 -2 向左移動 5 位,結果將是 -64 ,而非 64。
const result = 2 << 5;
console.log(result); // 64

// 二進制:
//      2 = 00000000000000000000000000000010
// result = 00000000000000000000000001000000

有符號的右移

由符號 >> 表示。將數值的向右移動指定位數,保留符號位,而且用符號位的值來填充空位。

有符號的右移與左移剛好相反。例如:將 64 向右移動 5 位,結果將是 2。
const result = 64 >> 5;
console.log(result); // 2

// 二進制:
//     64 = 00000000000000000000000001000000
// result = 00000000000000000000000000000010

無符號的右移

由符號 >>> 表示。將數值的全部位向右移動指定位數, 保留符號位,而且使用 0 來填充空位。

對於正數來講,無符號右移與有符號右移沒區別。對於負數來講:首先空位是由 0 來填充,而不是符號位的值;其次,會把負數的二進制碼(是正數二進制碼的反碼加1)當成正數的二進制碼,也就會致使結果很是之大。
const result1 = 64 >>> 5;
console.log(result1); // 2

// 二進制:
//     64  = 00000000000000000000000001000000
// result1 = 00000000000000000000000000000010

const result2 = -64 >>> 5;
console.log(result2); // 134217726

// 二進制:
//     -64 = 11111111111111111111111111000000
// result2 = 00000111111111111111111111111110

參考

《JavaScript高級程序設計》(第三版)

相關文章
相關標籤/搜索