【JS】温故知新: 从parseInt开始
工作中,几乎习惯了大量使用方便的工具库(如underscore、lodash),但是长期的依赖,却有可能在我们注意不到的地方出现黑天鹅,笔者最近就碰到了这样一件例子:
parseInt(9e-10);
本身是一句很简单的代码,只是把一个浮点数转换为整型,但是结果却出乎意料是9,所谓恶魔都藏在细节中,果不其然,parseInt的内部实现似乎并不是专门面向数字的。我们都知道parseInt有一些很有趣的特性:
//去掉单位“px”
let left = parseInt(YourDom.style.left);
//转换16进制数
let hex = parseInt('ff', 16)
但是,往往都忽略了为什么它会有这样的特性,于是笔者趁着周末适逢的大雨,饶有兴致的自己简单实现了一下parseInt:
let reg = /[^-\d]/;
let pureReg = /[^\d]/; function _slice(str, startIndex, endIndex){
if(endIndex > startIndex){
return str.slice(startIndex, endIndex);
}else{
return str;
}
} function $parseInt(val){
let _val = val; if(typeof(_val) !== 'string'){
_val = _val.toString();
} let strIndex = _val.match(reg) && _val.match(reg).index; if(strIndex == 0){
return NaN;
} let _str = _slice(_val, 0, strIndex); let negativeFlag = _str.indexOf('-') === 0 ? '-' : ''; if(negativeFlag){
_str = _str.slice(1);
} strIndex = _str.match(pureReg) && _str.match(pureReg).index;
_str = _slice(_str, 0, strIndex); return +(negativeFlag + _str);
}
当然,笔者并没有实现原api中radix的相关功能,所以代码其实是比较少的,下面简单梳理下思路:
首先,我们需要进行参数检测:
//如果参数的类型不为string和number,则调用它的toString方法,主要用于处理parseInt(Array)和parseInt(Number)的情况
if(typeof(_val) !== 'string'){
_val = _val.toString();
}
这样,我们得到的就是一个字符串了,接着我们找到字符串中第一个不为整型数据应该具备的字符的位置,例如('9e-10'中,e就不应该是整型应该具备的字符),然后通过字符串的slice方法取出满足的部分(如上例中的'9')。
接着,我们需要简单的处理下符号,毕竟整型包含正数和负数,规则其实和之前处理非法字符的思路是一致的:
//首先判断负号是否出现在最前面,是则将它取出来
let negativeFlag = _str.indexOf('-') === 0 ? '-' : ''; if(negativeFlag){
_str = _str.slice(1);
}
//然后再剩余的字符串中寻找负号,按之前的策略处理
strIndex = _str.match(pureReg) && _str.match(pureReg).index;
_str = _slice(_str, 0, strIndex);
然后,就可以得到一个parseInt方法了,笔者命名为$parseInt。
return +(negativeFlag + _str);
其实,回过头来,parseInt这样非常简单的方法内部需要考虑的情况也是非常的多的,特别如果还有'.'和'+',情况则更为复杂,parseInt的场景中只有'-',反而还算是比较简单的,不过也正由于它的这种特性,对于浮点数的处理才会出现parseInt(9e-10)===9的奇怪现象,不过笔者仅是使用了几个例子反推的内部实现,究竟parseInt具体应该是怎么实现的,还需要翻看一下文档才能真正明确。
随着前端圈的发展日趋完善,不断的框架、工具库层出不穷,常年居于顶层的我们可能都渐渐的远离了底层实现,但在某些具体的场景里,对这些底层实现的掌握,却有助于我们更好的处理好我们的日常工作,正如古人云“知其然,知其所以然”。其实,无论是工作,还是生活,保持一颗好奇心,我们的世界也会越来越大,越来越有意思。
P.S.本文中的$parseInt仅基于以下几个例子实现,仅作抛砖引玉使用,并非parseInt的完整实现,请注意:
parseInt([1]); //1
parseInt(+0); //0
parseInt(-1); //-1
parseInt(123.123); //123
parseInt('-123-345');//-123
【JS】温故知新: 从parseInt开始的更多相关文章
- JS全局函数parseInt和parseFloat
1.parsetInt parseInt(string ,radix)解析一个字符串,并返回一个十进制的整数:该方法是将字符串转成十进制整数 console.log(parseInt("01 ...
- 理解Js的parseInt(转)
parseInt() 方法首先查看位置 0 处的字符,判断它是否是个有效数字:如果不是,该方法将返回 NaN,不再继续执行其他操作.但如果该字符是有效数字,该方法将查看位置 1 处的字符,进行同样的测 ...
- js中parseInt()与parseFloat(),Number(),Boolean(),String()转换
js将字符串转数值的方法主要有三种 转换函数.强制类型转换.利用js变量弱类型转换. 1. 转换函数: js提供了parseInt()和parseFloat()两个转换函数.前者把值转换成整数,后者把 ...
- JS 数据类型转换
JS 数据类型转换 方法主要有三种 转换函数.强制类型转换.利用js变量弱类型转换. 1. 转换函数: js提供了parseInt()和parseFloat()两个转换函数.前者把值转换成整数,后者把 ...
- js 字符串转换数字
方法主要有三种转换函数.强制类型转换.利用js变量弱类型转换. 1. 转换函数: js提供了parseInt()和parseFloat()两个转换函数.前者把值转换成整数,后者把值转换成浮点数.只有对 ...
- js 获取小数点位数方法及 字符串与数字之间相互转换方法
1.获取小数点位数方法 a. 使用 js 中 subsrting,indexOf,parseFloat三个函数,代码如下: var s = "22.127456" ;//s 为 字 ...
- js 字符串转换成数字的三种方法
在js读取文本框或者其它表单数据的时候获得的值是字符串类型的,例如两个文本框a和b,如果获得a的value值为11,b的value值为9 ,那么a.value要小于b.value,因为他们都是字符串形 ...
- js 字符串转换成数字(转)
转换函数: js提供了parseInt()和parseFloat()两个转换函数.前者把值转换成整数,后者把值转换成浮点数.只有对String类型调用这些方法,这两个函数才能正确运行:对其他类型返回的 ...
- js字符串转成数字的三种方法
js读取的html代码中获得的值 ,统统是以字符串的形式呈现的,为了方便我们后面对数据的操作,有时候我们有必要进行转换一下. 方法主要有三种 转换函数.强制类型转换.利用js变量弱类型转换. 1. 转 ...
随机推荐
- codeforces 359A
#include<stdio.h> #define N 60 int map[N][N]; int main() { int n,m,i,j,flag; while(scanf(&qu ...
- 使用Spring-Session共享使用Session
前言: session共享策略有很多,常见的有粘性复制,高并发下效率查.tomcat-redis-session-manager无疑是一个挺好的方案,缺点要配置tomcat,有点复杂.最优的方案莫过于 ...
- JDBC示例(增删查改)
前提: 1.项目中引入MySQL的JAR包,POM参考如下配置: <!-- mysql-connector-java --> <!-- http://mvnrepository.co ...
- How to remote debug neutron
First of all, I will assume that you know how to use pydevd to remote debug normal python program. I ...
- 【SSO】--单点登录之过滤器(filter)
在单点登录的探索中.用到一个知识点:过滤器(filter).常见的几种验证:Authorization filters,验证用户是否有权限訪问页面:Action Filter,验证用户登录的时候是否用 ...
- Android网络爬虫程序(基于Jsoup)
摘要:基于 Jsoup 实现一个 Android 的网络爬虫程序,抓取网页的内容并显示出来.写这个程序的主要目的是抓取海投网的宣讲会信息(公司.时间.地点)并在移动端显示,这样就可以随时随地的浏览在学 ...
- AVAudioSessionCategory的选择
AVAudioSessionCategoryAmbient 或 kAudioSessionCategory_AmbientSound --用于非以语音为主的应用,使用这个category的应用会随着静 ...
- CodeIgniter RestServer中put请求获取不到參数的问题解决
近期用restserver遇到个蛋疼的问题,发现$this->put得到的參数都是null.查了一下发现.这貌似这个普遍问题,參见链接:https://github.com/chriskacer ...
- TQ2440 学习笔记—— 1、Windows平台下开发工具安装与环境建立
板子:广州天嵌公司的TQ2440,处理器为三星的S3C2440 1.开发工具的安装与环境建立 系统:win7 64位 SecureCRT软件:该软件能够取代Windows中的超级终端,是个非常好的串 ...
- Android 最火框架XUtils之注解机制具体解释
在上一篇文章Android 最火的高速开发框架XUtils中简介了xUtils的基本用法,这篇文章说一下xUtils里面的注解原理. 先来看一下xUtils里面demo的代码: @ViewInject ...