【前端】深入淺出Javascript中的數值轉換
由於Javascript是一門弱類型的語言,在我們的代碼中無時無刻不在發生著類型轉換,所以了解Javascript中的類型轉換對於了解我們認識Javascript的運行原理至關重要。
本文主要從數值轉換這一維度來剖析在JS中,數值轉換會遵循什麽樣的規則,有哪些用途?
哪些情況下我們會用到js中的數值轉換?
- 在傳統的js中,對元素進行變換、位移、改變大小時,我們經常需要對長度單位進行計算操作;
- 當我們提供了一個通用add函數,此時需要對傳入參數的類型進行限制,不能是非數字格式;
- 更多場景請關註知乎問答:JavaScript中 Number()函數在哪些場景中用到?
Javascript中存在哪些數值轉換方式?
我們都知道js中存在顯式類型轉換和隱式類型轉換,其中顯式類型轉換包含:
- Number()
- parseInt()
- parseFloat()
- 一元加和減操作符
隱式類型在js中的體現比較復雜,這裏簡單羅列以下幾種情況:
- 位運算符在操作非數值時,會使用Number()來對變量進行轉換,然後進行計算;
- 乘/除/減法操作符;
- 關系操作符(<,>,<=,>=);
- 相等操作符其中一個變量為數值時,會把另一個變量轉換為數值進行比較。
由於js的弱類型特性,隱式類型轉換其實是相對而言的,如果你了解了一段代碼的類型轉換方式,那麽它對於你而言,就可以被視為顯式轉換。
由於Javascript中的隱式類型轉換基本都是通過調用Number函數的方式進行的,所以這篇文章主要討論不同顯式類型轉換的區別。在討論之前,我們先看一段代碼示例:
1 var a = ‘+3.14159test‘; 2 3 var num1 = Number(a); // NaN 4 var num2 = parseInt(a, 10); // 3 5 var num3 = parseFloat(a); // 3.14159 6 var num4 = +a // NaN 7 var num5 = -a // NaN
Number函數
特點
Number()可以用於轉換任何類型。
ECMA規範關於Number轉換的規則描述:
https://tc39.github.io/ecma262/#sec-number-objects
轉換規則
- 如果參數是Boolean,則如果為true,返回1;false返回0;
- 如果數字類型,直接返回;
- null返回0,undefined返回NaN;
- 如果是對象,則首先調用valueOf方法,如果返回值能轉換為數值,則返回;否則調用toString方法,然後將返回值按照其他類型規則轉換後的內容返回;
- 如果是字符串
- 如果只包含數字類型,則返回該數字類型的十進制格式;如果前邊有-號,則返回負數;
- 空字符串返回0;
- 十六進制字符串返回十進制數字;如果前邊有-號,返回NaN;
- 如果非數字,返回NaN;
1 var num1 = Number(true); // 1 2 var num2 = Number(false); // 0 3 var num3 = Number(12); // 12 4 var num4 = Number(); // 0 5 var num5 = Number(null); // 0 6 var num6 = Number(undefined); // NaN 7 var num7 = Number(‘012‘); // 12 8 var num8 = Number(‘-012‘); // -12 9 var num9 = Number(‘ 0x12‘); // 18 10 var num10 = Number(‘-0x12‘); // NaN 11 var num11 = Number(‘12test‘); // NaN 12 var num12 = Number( // 12 13 { 14 valueOf: function (){ 15 return ‘012‘ 16 }, 17 toString: function () { 18 return ‘012test‘ 19 } 20 } 21 )
parseInt函數
特點
僅用於轉換字符串類型,首先會忽略字符串前面的空格。如果字符串一開始是數字或者加減號後邊跟數字,則返回該字符串一直到非數字截止。
ECMA規範關於parseInt轉換的規則描述
https://tc39.github.io/ecma262/#sec-parseint-string-radix
轉換規則
- 如果第一個參數非字符串或數字類型,則返回NaN;
- 第一個參數格式正常,第二個參數不傳值
- 如參數一開始的非空格字符不是非數字且非加減號,則返回NaN
- 如參數一以0x開頭,則以十六進制來解析字符串,並返回該字符串的十進制格式;
- 如參數一以0開頭,則在es3標準中按照八進制來解析,es5標準中按照十進制來解析,最終返回十進制格式;(很重要,不了解會導致一些低版本瀏覽器莫名其妙的問題)
- 第二個參數傳值,首先會將參數二進行Number()轉換
- 如參數二能轉換成一個非0數字,則將參數一按照對應進制進行轉換
- 如參數二不能轉換成一個非0數字,則按照參數二為空進行處理
1 var num1 = parseInt(‘ 0xf‘); // 15 同parseInt(‘ +0xf‘) 2 var num2 = parseInt(‘ -0xf‘); // -15 3 var num3 = parseInt(‘ 12test‘); // 12 4 var num4 = parseInt(‘f‘); // NaN 5 var num5 = parseInt(‘f‘, 16); // 15 6 var num6 = parseInt(‘015‘, 8); // 13 7 var num7 = parseInt(‘15.34‘); // 15 8 var num8 = parseInt(‘f‘, ‘0x10‘); // 15
parseFloat函數
特點
與parseInt類似,但只能接收一個參數,傳入字符串只會按照10進制進行解析,會將傳入的字符串解析成Double類型數字。
ECMA規範關於parseInt轉換的規則描述
https://tc39.github.io/ecma262/#sec-parsefloat-string
轉換規則
- 如果第一個參數非字符串或數字類型或點字符,則返回NaN;
1 var num1 = parseFloat(‘ 15.34.43‘); // 15.34 2 var num2 = parseFloat(‘0x123.45‘); // 0 因為不支持十六進制 3 var num3 = parseFloat(‘ 012.0test‘); // 12
一元加和減操作符
一元加操作符的功能完全和Number()函數一致;一元減操作符是在加操作符的基礎上取負值
小結
當我們可以確定被轉換的變量類型是string類型時,推薦優先使用parseFloat,可以當被轉換變量為小數的正常使用;當使用parseInt時,推薦使用第二個參數來確定參數一的進制類型,避免因為不同瀏覽器的兼容問題;
在寫作過程中,越寫越發現牽涉到的知識點很多,或許很多地方存在紕漏、誤差。如有問題,還請指正!!!
【前端】深入淺出Javascript中的數值轉換