zoukankan      html  css  js  c++  java
  • 关于 parseInt 的一道有意思的面试题

    看完标题,入坑过的同学脑海里很快会浮现出这道经典面试题,没碰到过的同学不妨跟着楼主先来复习一遍 parseInt 的用法(主要参考 MDN)。

    parseInt 是 JavaScript 中的一个全局函数(顶级函数),它会将给定的字符串以指定基数(radix/base)解析成为整数。

    它的语法非常简单:

    parseInt(string, radix)
    

    第一个参数 string 是要被解析的值,如果参数不是一个字符串,则将其转换为字符串,字符串开头的空白符将会被忽略。而第二个参数 radix 是一个 2 到 36 之间的整数值,用于指定转换中采用的基数,如果不传入,默认是 10,即按照十进制转换,这里要注意一点,如果第二个参数传入 0,和传入 10 以及不传入第二个参数等效。函数返回一个整数值,如果解析过程中发生错误,将返回 NaN。

    返回 NaN 的主要有以下几种情况:

    • 被解析参数的第一个字符无法被转化成数值类型
    • 被解析参数数值太大,不是 radix 进制下的合法数字
    • radix 不在 [2, 36] 范围内(注意其实 0 也是可以的)
    console.log(parseInt('hello', 2)); // NaN
    console.log(parseInt('3', 2)); // NaN, 3 不是合法的二进制数字
    console.log(parseInt('3', 100)); // NaN
    

    其实实际开发中我很少用 parseInt,而是用 +~~ 代替,因为它实在是太长了,但是很显然 parseInt 的使用范围更广。

    简单回顾了 parseInt 的用法,我们来看这道题:

    let ans = ["1", "2", "3"].map(parseInt);
    console.log(ans);
    

    和大多数人一样,我的第一反应也是返回 [1, 2, 3],这个时候我们有必要回顾下 Array.prototype.map,该方法的参数是一个函数,而该函数又可以接受三个参数,分别表示数组元素的值,数组元素的在数组中的索引,以及对于数组的引用。一般来说我们直接在 map 方法中传入匿名函数,但是如果这个函数是在外面定义的,传入的是方法名呢?

    let fn = (...a) => {
      console.log(a);
    };
    
    let ans = ["1", "2", "3"].map(fn);
    
    // [ '1', 0, [ '1', '2', '3' ] ]
    // [ '2', 1, [ '1', '2', '3' ] ]
    // [ '3', 2, [ '1', '2', '3' ] ]
    

    我们可以看到,如果没为该函数指定参数,那么这三个参数都会被传入!

    我们再回到这道题,parseInt 方法是可以传入 1-2 个参数的,所以 map 传入的三个参数,其实是都会被传给 parseInt 方法的,只是 parseInt 会使用前两个参数而已

    console.log(parseInt('12', 10, 'ignore')); // 12
    

    所以整个过程差不多是这样的:

    let fn = (item, index, array) => {
      return parseInt(item, index, array);
    };
    
    let ans = ["1", "2", "3"].map(fn);
    console.log(ans); // [ 1, NaN, NaN ]
    

    其实就是计算如下:

    console.log(parseInt("1", 0)); // 1
    console.log(parseInt("2", 1)); // NaN
    console.log(parseInt("3", 2)); // NaN
    

    看懂了吧不妨再试试下面这道:

    let ans = "1 2 3".replace(/d/g, parseInt);
    console.log(ans);
    

    原理是一样的,当 replace 的第二个参数是函数的时候,该函数的第一个参数是匹配模式的字符串,接下来的参数是与模式中的子表达式匹配的字符串,可以有 0 个或者多个这样的参数。接下来的参数是一个整数,声明了匹配在 StringObject 中出现的位置,最后一个参数是 StringObject 本身。

    还是一样,打印出来看看呗:

    let fn = (...a) => {
      console.log(a);
    };
    
    let ans = "1 2 3".replace(/d/g, fn);
    
    // [ '1', 0, '1 2 3' ]
    // [ '2', 2, '1 2 3' ]
    // [ '3', 4, '1 2 3' ]
    

    接下去就简单了,就是计算下面的表达式了:

    console.log(parseInt("1", 0, '1 2 3')); // 1
    console.log(parseInt("2", 2, '1 2 3')); // NaN
    console.log(parseInt("3", 4, '1 2 3')); // 3
    

    最后再加一道题:

    console.log(parseInt(Infinity, 19))
    

    前面说了,第一个参数 string 是要被解析的值,如果参数不是一个字符串,则将其转换为字符串,所以 Infinity 被转换成 "Infinity",而 19 进制数中,最大的字符就是 i,代表 18,所以解析的时候遇到 n 就停了,所以输出 18

  • 相关阅读:
    常用正则
    存储过程里循环读取Array
    倒倒系列1
    利用HttpHandler生成静态页面
    古代人用拼音吗?
    确认Email无法复制粘贴
    C#调用OpenCV(一) 配置VS+OpenCV+Emgu cv
    ArcGIS Desktop9.3 (需要双击注册文件的破解包)在64位操作系统上的安装方法
    WebLogic console页面,localhost能登陆,IP不能登录
    javascript prototype学习(一)prototype的用处
  • 原文地址:https://www.cnblogs.com/lessfish/p/6489703.html
Copyright © 2011-2022 走看看