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中的隱式類型轉換總會在我們意想不到的情況下發生,在數據處理中尤爲如此,所以當請求到後端傳送的數據後,爲避免進行隱式類型轉換,通常需要做到以下兩步:
- 將請求過來的數據進行一次複製,避免在無意中修改一些數據。
- 深刻理解隱式類型轉換的機制與原理,避免不必要的數據轉換。
- 在確認某種數據類型後再作對應的運算操作。
本文有諸多地方參考了莫莫的github
現在去看看你在項目中的代碼是否有許多隱式類型轉換的操作吧!
奮鬥是這麼個過程,當時不覺累,事後不會悔。走一段再回頭,會發現一個更強的自己,宛如新生