JavaScript隱式類型轉換進階

JavaScript隱式類型轉換進階

JavaScript中有許多的隱式類型轉換,合理運用它們能對項目的開發提供更便捷的處理方式,目前涉及到隱式類型轉換的的運算符主要有:數學運算符(加減乘除,取模,自增等)if,alert語句邏輯運算符(&&,||,!等)關係運算符(==, >,<等)

數學運算符的隱式轉換規則

變量表達式在進行數學運算時,會根據變量的類型進行相關的運算操作,此時的變量會進行一些隱式類型轉換,具體的規則如下:

  • 減法-乘法*除法/取餘%減等-=除等/=模等%=自減--自增++正+負-

    1.如果運算符兩側的變量都是基本數據類型或數組,調用Number()方法將變量轉換成數字進行運算;

    2.如果運算符中有對象,則調用對象的valueOf()方法,如果返回基本類型,轉步驟1;如果valueOf()方法返回的是對象,則對變量調用toString()方法,如果返回基本類型,轉步驟1,否則返回NaN

    '4' / 2;       // 2
    '1245' * 10;   // NaN
    [2] / 2;       // 1
    [2,3] / 2;     // NaN
    [2] * [5];     // 10
    let test = {valueOf: () => '123'}
    ++test;        // 124
    test = {valueOf: () => [2], toString: () => '200'};
    test % 3;      // 2
    test = {valueOf: () => [2], toString: () => ['200']};
    test--;        // NaN
    
  • 加法+加等+=

    1.如果有一側的變量爲字符串,則進行字符串的拼接;

    2.如果兩側的變量爲出字符串的其他基本數據類型,則調用Number()方法,進行數學運算;

    3.如果有一側是數組,則調用數組的toString()方法,然後進行字符串的拼接;

    4.如果運算符中有對象,則調用對象的valueOf()方法,如果返回基本類型,根據返回的類型轉步驟1-2;如果valueOf()方法返回的是對象,則對變量調用toString()方法,如果返回基本類型,根據返回的類型轉步驟1-2,否則返回NaN

    2 + 3;          // 5
    '2' + 3;        // '23'
    [2] + [5,6];    // '25,6'
    let test1 = {valueOf: () => 3};
    test1 += 2;     // 5
    test1 = {valueOf: () => [], toString: () => '55'};
    test1 + 2;      // '552'
    test1 = {valueOf: () => [], toString: () => {}};
    test1 + 2;      // NaN
    

邏輯運算符的隱式轉換規則

邏輯運算符的隱式轉換規則是根據運算符兩側的變量調用Boolean()方法轉換成Boolean值再進行邏輯運算,邏輯運算=符主要有或||與&&非!.

  • 或||

    對第一個值調用Boolean()方法,如果爲true,則返回第一個值;否則返回第二個值

    // 可以讓某個方法或表達式在特定的情況下被調用
    let re = !isUsable || (123 + 20);            // 143
    34 || 43;            // 34
    '' || 43;            // 43
    
  • 與&&

    對第一個值調用Boolean()方法,如果爲true,則返回第二個值,否則返回第一個值

    '' && 2;       // ""
    {} && 4;       // 4
    // 讓某個方法在特定的情況下被調用
    let res = isShowDialog && showDialog();
    
  • 非!

    對變量調用Boolean()方法,然後對Boolean值取反

    !false;          // true
    !{};             // false
    ![];             // false
    

關係運算符的隱式轉換規則

關係運算符通常是將變量進行比較,對於不同類型的變量而言,其比較的規則有有所差別,詳細規則如下:

  • 大於>小於<大於等於>=小於等於<=

    1.如果有一個變量爲數字,則將另一個值轉換成數字再進行比較,轉換規則同數學運算符;

    2.如果有兩個變量爲字符串,則一個一個地比較字符串對應的UNICODE編碼;

    3.如果有一個變量爲字符串,另一個爲對象,則先調用對象的valueOf()方法,如果返回數值,轉步驟1;如果返回字符串,轉步驟2;如果返回對象,則調用toString()方法,如果返回數值,轉步驟1,如果返回字符串,轉步驟2

    4.如果有一個變量是布爾值、null、undefined,則將其轉換成數值,再進行比較;

    5.如果一個變量爲字符串,另一個變量爲數組,如果數組第一個元素爲字符串,將此字符串與第一個變量比較UNICODE值;如果數組第一個元素爲數值,將第一個變量轉換成數值再進行比較。

    5 > '4';          // true
    50 > '51';        // false
    '51' > '5001';    // true
    '51' > [50];      // true
    '51' > ['5001'];   // true
    let test2 = {valueOf: () => [23]};
    51 > test2;       // true
    22 > test2        // false
    test2 = {valueOf: () => ['233']};
    51 > test2;       // false
    test2 = {valueOf: () => [],toString: () => 55};
    51 > test2;       // false
    
  • 等等==不等!=

    1.如果其中一個變量是數字,同上;

    2.如果兩個變量爲字符串,同上;

    3.如果兩個變量都爲對象,直接比較兩個變量的引用地址是否相同;

    4.如果有個變量爲字符串,另一個爲對象,同上;

    5.如果有一個變量是布爾值、null、undefined,除非另一個變量也是對應的值,否則都爲false;

    6.如果一個變量爲字符串,另一個變量爲數組,同上。

    5 == '5';                       // true
    51 == {valueOf: () => 51};      // true
    51 == {valueOf: () => [], toString: () => 51}; // true
    '51' == {valueOf: () => [], toString: () => '51'}; // true
    '51' == '51';                   // true
    {valueOf: () => 123} == {valueOf: () => 123};  // false
    [2] == 2;                       // true
    ['2'] == '2';                   // true
    ['2'] == 2;                     // true
    
  • 全等===不全等!==

    1.如果兩側數據類型不相等,返回false;

    2.如果兩側都是數字,比較數字大小;

    3.如果兩側都是字符串,比較字符串是否相同;

    4.如果兩側都是對象,比較對象引用地址是否相同;

JS中的隱式類型轉換總會在我們意想不到的情況下發生,在數據處理中尤爲如此,所以當請求到後端傳送的數據後,爲避免進行隱式類型轉換,通常需要做到以下兩步:

  1. 將請求過來的數據進行一次複製,避免在無意中修改一些數據。
  2. 深刻理解隱式類型轉換的機制與原理,避免不必要的數據轉換。
  3. 在確認某種數據類型後再作對應的運算操作。

本文有諸多地方參考了莫莫的github
現在去看看你在項目中的代碼是否有許多隱式類型轉換的操作吧!

奮鬥是這麼個過程,當時不覺累,事後不會悔。走一段再回頭,會發現一個更強的自己,宛如新生

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章