1.如何實現呢
我的思路如下:
- 對於
非number類型
或者是NaN
的數據,我們直接原樣返回該數據。 - 對於小數部分的位數,小於我們要保留的位數,我們也直接原樣返回該數據。
- 滿足條件的數據,先將數據轉爲字符串,然後,通過
split('.')
方法截取。這樣,我們得到了數據的整數部分,和小數部分了。如:
var str = '12.369';
str.split('.');
// ["12", "369"]
接下來,我們只針對小數部分做些判斷就可以了。比如,我們要保留2位小數,那麼我們需要對小數的第三位用“四捨五入
”的方式判斷是否進一。拿上面的例子做個示範:對於小數部分369
。我們需要截取36
和9
,接着將36
轉爲0.36
。然後,我們對9
進行判斷,是否要將0.36
加上0.01
。最後,我們再加上整數部分12
,就可以了。
(注意:我們這裏必須最後再加上整數部分。因爲會有如下的坑:)
這個涉及到js存儲數據的精度問題,這裏不多說。
2.代碼
- 其實對於
非number類型
或者是NaN
的數據,或者小數位數小於要求保留的位數
,你將它轉爲字符串再截取後,數組的第二位要麼undefined,要麼第二位字符串的length小於保留的位數
,我覺的這樣判斷處理會更簡便。
// 保留幾位小數
// 0.001 + 12.334 = 12.334999999999999 這個也是不行的
// 改進方法:先加小數部分,然後,加上整數部分
function retainDecimal(data, deci) { // data 數據, deci 幾位
if (typeof data === 'number') {
const splitArr = String(data).split('.'); // 字符串截取
const integerPart = splitArr[0]; // 整數部分
const deciPart = splitArr[1]; // 小數部分
// 小數位數小於要保留的位數時,直接返回
if (!deciPart || deciPart && (deciPart.length < deci + 1)) return data;
const frontDec = deciPart.substr(0, deci); // 保留幾位
const isAdd = +(deciPart.substr(deci, 1)) >= 5 ? 1 / Math.pow(10, deci) : 0;
return parseFloat(frontDec / Math.pow(10, deci)) + isAdd + parseFloat(integerPart);
}
return data;
}