字符串转换成数字方法总结

前端开发的重要性表现在众多方面,其中之一就是可以减轻服务器的负担,把一些规则性,格式性的错误直接就过滤掉了,而这些判断中,就有一个很基础的判断就是数字的判断。

写在前面

首先一点要明白,当我们在html元素中获取到的数据,都是字符串的,只是字符串的格式不同而已,这里所说的判断数字,就是要判断这些字符串哪些是纯数字组成的。

这里只说一些最基本的判断,就是判断是否为数字,并把该数字字符串转变成number类型,以供后面更深层次的判断。

判断方法

这个判断其实是分为很多种类的,根据不同的使用环境,方法的选择也是不同的。那么先看下面几种判断,到底适合在什么时候使用呢?


Number("111");     //111
Number("111a");    //NaN
parseInt("111a");  //111
parseInt("111");   //111
parseInt("a111");  //NaN
"111a"-0;          //NaN
"111"*1;           //111
"111">>0;          //111
"111a">>0;         //0
"-111">>0;         //-111
"-111">>>0;        //4294967185


在我这个时候,能想到的,也只有这几种方法,可以把字符串转变为数字的了。看下上述例子中,基本上可以分为三种情况说明。

1:严格型转换

严格型,我是这么认为的,只有完全是数字的,才会被转换为有效数字,而且它的都会被转换为NaN值。

比如上述代码中的Number方法,和使用减法和乘法的示例。该方法中,只有完全由数字组成的字符串才能转换为有效的数字,就如上述示例中看到的样子。

但是这里有些例外情况:


Number("");         //?
Number(null);       //?
Number(undefined);  //?

""-0;               //?
null-0;             //?
undefined-0;        //?


这在严格类型中,属于比较特例的地方了,而这里使用这两种方法,却得到了完全相同的结果(假设您已经自己测试过了)。

因为在浏览器内部,执行加减乘除操作时,如果元素不是number类型,浏览器也是会自动钓鱼Number方法的,所以,才导致这两种方法,基本上时完全相同的表现了。

至于哪种方法更优,有更高的效率,在我看来:

1:如果使用操作符的写法更容易记住,也更方便操作,对于使用者会更好。

2:同时,操作符的使用方法,在浏览器内部,还需要再次调用Number的方法,在性能方法应该是低于直接调用Number方法的。

3:其实,这些都没有什么需要担心的,我自己搞了个小的例子测试了下,它们的性能基本上时没有什么差距的,执行十万次进行操作,耗费时间也就几十到百毫秒左右,几乎可以忽略。

所以,个人觉得,还是使用操作符更好用些。

同时,undefined会直接变成NaN这个没有问题吧,因为undefined是属于基本类型中的一种,不为数字。

null是属于object类型的,对于object类型的数据,当执行变成数字操作时,首先object类型会调用Object对象上的valueOf方法,获取到对应的值,而null值会被转换为0处理的(记忆里是这样的),所以,就有了上面的情况。比如:null+10=10。

2:纠错型转换

之所以叫纠错型转换,是因为,这个时候,代码假设你得到的数字字符串是正确的,只是因为不小心,出现了一点错误。

该种方法,就是前面示例中的parseInt方法了。该方法,只会取得目标字符串的前几位数字,直到非数字或者字符串结尾。

所以,就有下面的示例:


parseInt(null);       //?
parseInt(undefined);  //?
parseInt("");         //?
parseInt("123a");     //?


其中,nullundefined是特殊的类型,这里只是用来做对比的。

让我们来想一下,如果自己实现parseIntNew的一个API可以怎么做?只取前几位数字,当然使用强大的replace和正则表达式了。

比如这样实现:


function parseIntNew(str){
	
    //转换为字符串类型,为接下来使用replace方法做前提
    str = ""+str;

    str = str.replace(/^(\d+)[^\d]*$/,function($1,$2){
        return $2;
    });
    //经过replace之后,str只有两种情况,
    //str = ""
    //str = "a.."
    //str = "1.."
    if(str === ""){
        //过滤掉str= ""的值,因为 ""-0=0
        return NaN;
    }else{
        //会把非全数字的字符返回NaN
        return str - 0;
    }
}

var obj321 = new Number("321"),
    objStr = new String("12334a");

console.log(parseIntNew(null));
console.log(parseIntNew(undefined));
console.log(parseIntNew("12a"));
console.log(parseIntNew("12"));
console.log(parseIntNew(obj321));
console.log(parseIntNew(objStr));
console.log("line");
console.log(parseInt(null));
console.log(parseInt(undefined));
console.log(parseInt("12a"));
console.log(parseInt("12"));
console.log(parseInt(obj321));
console.log(parseInt(objStr));


当然,这些自定义的一些实现方法,根据不同人不同的思路,不同的代码编写喜好,都是不同的,所以,这里只是给出了我自己的想法而已,金控参考。

3:默认值型转换

取默认值转换,就是那种,当被转换字符串为非数字时,不是像上面返回NaN或者取字符串最初的前几位数字,而是直接把该字符串转换为0数字。

实现方法,就是前面看到的位操作符,看下~~


var obj321 = new Number("321"),
    objStr = new String("12334a");

console.log(null >> 0);
console.log(undefined >> 0);
console.log("12a" >> 0);
console.log("12" >> 0);
console.log(obj321 >> 0);
console.log(objStr >> 0);


这个其实没有可以多说的,这也是我最近才发现的一种方法,所以就总结了一下,把自己知道的几种方法,组成了该篇文章。

总结

这里只说了各方法的一些特性,至于什么时候,选择什么样的用法,就看使用场景了,这里不多说了,在我看来,我们最常用的应该是第一种“严格型”转换,接下来“默认值型”转换,而纠错型转换,在我看来,就有点意义不大的样子了,但总归是一种方法吧,所以就列在了这里。

对于其他的一些常用方法,暂时没有接触到,或者我本人还没有发现,如果您知道,恳请指教。谢谢!

本文地址:http://www.zhangyunling.com/?p=389

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>