1. 程式人生 > >學習 JavaScript (四)核心概念:操作符

學習 JavaScript (四)核心概念:操作符

JavaScript 的核心概念主要由語法、變數、資料型別、操作符、語句、函式組成,前面三個上一篇文章已經講解完了。後面三個內容超級多,這篇文章主要講解的是操作符。

操作符

什麼叫做操作符?

這是一種工具,幫助我們操作字串、數字值、布林值,乃至物件,運用一些操作符能夠讓程式碼更簡潔、計算更高效。它包括以下幾種:

  • 賦值操作符
  • 一元操作符(加、減)
  • 位操作符
  • 關係操作符
  • 相等操作符

01 賦值操作符

賦值操作符就是我們常見的 “=”,作用就是把右邊的值賦給左邊的變數。比如:

let a = 1;

如果複雜一些(效能上不會有提升,看起來牛*一點而已),就是結合後面要碰到的操作符,變成這樣:

*= ; // 乘/賦值

// 舉例
let num = 10;
num = num * 10; // 和下面的用法效果一樣
num *= 10;

下面的複雜賦值操作符如下:

/= ; // 除/賦值
%= ; // 模/賦值
+= ; // 加/賦值
-= ; // 減賦值
<<= ; // 左移賦值;
>>=; // 有符號右移;
>>>= ; // 無符號右移;

02 一元操作符

記住:只對一個數值進行操作的符號叫做一元操作符,而不是指操作符自身的數量。

遞增操作:兩個加號 ++

前置操作 ++i ,i 先自己加上 1 ,然後拿著計算後的 i 值進行下一步計算。

let i = 1;
let result = ++i + 20 
console.log(i) // 2
console.log(result) // 22

後置操作 i++,先進行下一步計算,然後再自己加上1。

let i = 1;
let result = i++ + 20 
console.log(i) // 2
console.log(result) // 21

遞減操作:兩個加號 --

遞減操作和遞增操作的規則一樣,-- 符號在前面就先進行遞減操作,否則就等接下來的計算進行完再遞減。

前置操作 --i ,i 先自己減去 1 ,然後拿著計算後的 i 值進行下一步計算。

let i = 1;
let result = --i + 20 
console.log(i) // 0
console.log(result) // 20

後置操作 i--,先進行下一步計算,然後再自己減去1。

let i = 1;
let result = --i + 20 
console.log(i) // 0
console.log(result) // 21

統一記憶成:符號在前,馬上加減

加和減操作符

前面講的是兩個相同的符號聯合起來操作一個數值,而家下來介紹的這個操作符只有一個。

+ 或者 -,對於數值來說,+ 沒有任何作用,對於 -

來說,把正數變成負數而已。

如果我們把操作符用在其他資料型別上,會發生怎樣的情況呢?直接看例子:

let a = "01";
a = +a; // 1

let b = "1.1";
b = +b; // 1.1

let c = "z";
c = "z"; // NaN

let d = "true";
d = "true"; // 1

let e = 1.1;
e = 1.1; // 1.1

let o = {
    valueOf: function(){
        return -1;
    }
} // 如果沒有看懂這個物件的寫法,不用著急,後面會針對物件做進一步的解釋。
o = +o ; -1

-操作則是在+操作的結果前面加上負號(-)而已。其他型別的資料的轉換規則依然不變。

03 位操作符

位操作符是在最基本的、最底層的水平上對數值進行操作,也就是在記憶體中直接對二進位制進行操作。

JavaScript 中的所有資料都是按照 64 位儲存的,但是位操作符並不能直接對 64 位的資料進行操作,而是將其轉換成 32 位的,操作完成後,再轉換成 64 位的,所以我們真正關心的是計算機如何操作 32 位的數值。

對於有符號的整數,二進位制從右往左數,32 位中的前 31 位表示整數的值,第 32 位是符號位,表示數值的符號,0 表示正數,1 表示負數。比如 數值 18 表示成二進位制為:

0     0000000000000000000000000010010
符號位

寫成簡潔版的:

10010

31 位中每一位都表示 2 的冪,所以從二進位制轉換成數值:

(2^4 x 1) + (2^3 x 0) + (2^2 x 0) + (2^1 x 1) + (2^0 x 0) = 18

這是正數的二進位制表達方式,負數的二進位制需要用到二進位制補碼。步驟如下:

  1. 求這個數值的絕對值的二進位制;
  2. 求二進位制反碼,將 0 替換成 1,將 1 替換成 0 ;
  3. 得到的二進位制反碼加 1 ;

舉一個例子(-18):

-18 的絕對值等於 18:

0     0000000000000000000000000010010

求二進位制反碼:

1     1111111111111111111111111101101

反碼加 1

1     1111111111111111111111111101110

最終得到的結果就是 11111111111111111111111111101110 。但是計算機給我們看的結果卻不是這樣,把 -18 轉換成字串會發現得到的結果是“-10010”,計算機隱藏了計算過程,直接展示友好的結果而已,別被騙了。

因為是底層操作,所以應用位操作的計算方式會比普通計算方式要快:

  • 按位非(NOT)
    • 符號:~ ;
    • 作用物件:一個數值(數字、字串、布林值、物件);
    • 操作:把運算元變成相反數再減去一 ;
    • 例子: ~2 == -3~-2 == 1~true == -2
  • 按位與(AND)
    • 符號:& ;
    • 作用物件:兩個數值;
    • 操作:將兩個數值的二進位制形式中的每一位對齊,然後依據普通的與操作進行合併,把 1 看成 true,把 0 看成 false , 即 1 和 1 組合是 1 ,1 和 0 組合是 0 , 0 和 0 組合是 0 。得到的二進位制再轉換成 十進位制就可以了;
    • 例子: 25 & 3 == 1
  • 按位或(OR)
    • 符號:| ;
    • 作用物件:兩個數值;
    • 操作:和按位與的操作類似,與之不同的是,按位或操作時,只要碰到 1 就返回 1 ,只有兩個對應的位全部為 0 時才返回 0 ;
    • 例子:25 | 3 == 27
  • 按位異或(XOR)
    • 符號:^ ;
    • 作用物件:兩個數值;
    • 操作:有且僅有一個位是 1 ,另一個位是 0 ,才返回 1 ,否則都返回 0,即 1 和 1 也返回 0;
    • 例子:25 ^ 3 == 26
  • 左移
    • 符號:<< ;
    • 作用物件:一個數值;
    • 操作:將數值的所有位向左移動指定的位數,右側多出來的空位由 0 進行填充;
    • 例子:2 << 5 == 64,2 向左移動 5 位,左移不會影響運算元的符號位,即 -2 ; ,左移後的結果將會是 -64。
  • 右移
    • 符號:>> ;
    • 作用物件:一個數值;
    • 操作:將數值的所有位向右移動指定的位數,符號位不動,左側多出來的空位由 0 進行填充;
    • 例子:64 >> 5 == 2,64 向右移動 5 位,右移不會影響運算元的符號位,即 -64 ,右移後的結果將會是 -2。
  • 無符號右移
    • 符號:>>>;
    • 作用物件:一個數值;
    • 操作:將數值的所有位向右移動指定的位數,左側多出來的空位由 0 進行填充,這個時候符號位也要向右移動。可以知道,對於正數而言,這個操作和右移是一樣的結果,但是對於負數來說,因為符號位是 1 ,移動後要計入最終結果;
    • 例子:-64 >>> 5 == 134217726

04 布林操作符

在上述位操作符中的按位非、按位與、按位或,我們已經簡單介紹了一些跟布林操作類似的用法。

總的來說,布林操作的地位跟相等操作符(==、===)的地位是一樣的,一共右三種:非(NOT)、與(AND)、或(OR)。

  • 邏輯非
    • 符號:!;
    • 作用物件:一個數值;
    • 操作:先將數值轉換成一個布林值,再取反;
    • 例子:
    !false; //true
    !true; //false
    !null; //true
    !{}; // false
    !0; //true
    !123; //false
    !""; //true
    !"abc"; //false
    要點:此時連用兩個 “!”,則跟布林轉換函式 Boolean() 的作用是一樣的,即還原了數值本身代表的布林值。
  • 邏輯與
    • 符號:&&;
    • 作用物件:兩個數值;
    • 操作:比較兩個數值的布林值,返回結果(不一定是布林值);
    • 例子:
    true && true; //true
    true && false; //false
    false && true; // fasle
    false && false; // false

要點:

  1. 這裡的 true 和 false,可以替換成別的數值型別,比如物件、null等
  2. 邏輯與是短路操作,只要第一個運算元或者運算元的轉換值是 false ,計算終止,直接返回 false 。如果是 true 的話再返回後面的值。
  3. 在寫判斷語句的時候經常會用到。
  • 邏輯或
    • 符號:||;
    • 作用物件:兩個數值;
    • 操作:比較兩個數值的布林值,返回結果(不一定是布林值);
    • 例子:
    true || true; //true
    true || false; //true
    false || true; // true
    false || false; // false

要點:

  1. 邏輯或也是短路操作,只要第一個運算元或者運算元的轉換值是 true ,計算終止,直接返回第一個運算元。如果是 false 的話,返回第二個運算元。
  2. 利用邏輯或的性質,我們在定義變數的時候可以給它找個備胎,降低 Bug 發生率。

04 乘性操作符

乘性操作符包括三種:乘法、除法、求模。在 JavaScript 中,運算元為非數值的情況下也能計算。比如:

"10" * 2 ; // 計算結果為 20

可以看得出來,計算機自動執行了型別轉換,如果參與的運算元不是數值,會先用 Number() 函式轉換。

  • 乘法:
    • 符號: *
    • 舉例:4 * 5

有三點需要注意:

  1. 乘積超過 JavaScript 範圍,用 Infinity表示無窮大 或者 -Infinity 表示負無窮大;
  2. Infinity 和 0 相乘是 NaN;
  3. 其中一個運算元是 NaN,則結果是 NaN。因為 Number() 轉換非數值型字串是 NaN,所以非數值型字串和數字相乘就是 NaN 。其他的規則與乘法操作符類似。

  • 除法:
    • 符號: /
    • 舉例:44 / 11 ;等於 4 有一點需要注意:如果 Infinity 被 -Infinity 除,那麼結果是 NaN。 ---
  • 求模:
    • 符號: %
    • 舉例:26 % 5 ;等於 1

求模就是取餘數。

05 加性操作符

加法和減法都被稱作是加法操作符。在這裡說明一下,加性操作符也會強制轉換資料型別。

  • 加法:
    • 符號: +
    • 舉例:1 + 1

需要注意的是,

  1. 如果兩個運算元都是字串,那麼直接拼接起來返回結果;如果其中一個運算元是字串,那麼就把另一個運算元轉換乘字串再拼接起來。
  2. 利用 Chrome 的 console 命令視窗,實驗得到如下的規則:
{} + 11; // 11
11 + {}; // "11[object,object]"

false + 1; // 1 ; 運算元可以調換位置,結果不變
true + 1; // 2 ; 同上
null + 1;// 1 ;同上
undefined + 1 ; // NaN;同上
  • 減法:
    • 符號: -
    • 舉例:2 - 1

減法兩邊的運算元和加法的區別是,無論是字串還是物件,都應該轉換成數值,再進行計算。不存在字串相減的情況。

06 關係操作符

關係操作符就是小學的時候學過的小於(<)、大於(>)、小於或等於(<=)、大於或等於(>=)。

JavaScript 中,使用關係操作符比較兩個運算元後,返回的結果是布林值(true、false)。

需要注意的是,

  1. 當比較的兩個數都是數值時,直接比數字大小;

  2. 如果都是字串則比較對應位置的字元編碼值。比如:

    "Brick" < "apple"; //返回的是 true,因為 B 的字元編碼是 66 ,而 a 的字元編碼是 97
    
    "23" < "3"; // 返回 true,因為 2 的字元編碼是 50 ,3 的字元編碼是 51 。
  3. 如果其中一個是數字,則把另一個運算元變為數值以後再比較;
  4. 任何資料型別和 NaN 比較都是返回 false。

這裡有個小思考:如果 A、B 表示兩個資料,有 A > B 不成立(false),則 A <= B 是否成立?

07 相等操作符

JavaScript 提供兩種比較方案:

  • 相等(==)和不相等(!=),會把運算元轉換成相似的型別再比較。

    "5" == 5; //true
    • null 和 undefined 是相等的;
    • 如果有一個運算元是 NaN 則返回 false ;
    • NaN 和 NaN 不相等,NaN 返回 true ;
  • 嚴格相等(===)和嚴格不相等(!==),直接比較,不轉換資料型別,使用嚴格相等操作符,有一丁點不相等就返回 false。

    "5" === 5; //false
    • null 和 undefined 是不嚴格相等的

總之,在實際使用過程種,建議是使用嚴格相等和嚴格不相等。

08 條件操作符

條件操作符也被稱作是三目運算子,用法如下:

let a = 條件語句 ? 1 :2

如果條件語句返回的是 true ,則把 1 賦值給 a,如果是 false, 則把 2 賦值給 a。

返回一個較大值,我們就可以不用謝一個 if 語句,直接按照下面這種寫法就可以實現:

let a = (number1 > number2) ? number1 : number2

歡迎大家關注微信公眾號:視覺化技術( visteacher )

不僅有前端和視覺化,還有演算法、原始碼分析、書籍相送

各個分享平臺的 KurryLuo 都是在下。

用心學習,認真生活,努力工作!