前端练习11 手写实现parsenInt方法

本文介绍了手写实现JavaScript的parseInt方法,探讨了实现过程中的关键知识点,包括字符串数字转换、Unicode编码与ASCII码的关系,以及如何处理进制转换。文章还讨论了使用reduce方法替代for循环的实现方式,并提供了相关学习资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

手写parseInt的实现:要求简单一些,把字符串型的数字转化为真正的数字即可,但不能使用JS原生的字符串转数字的API,比如Number()

实现

这道题考察的知识点有下面几个方面:

1 parseInt的使用

parseInt接受两个参数,第一个参数s是要转换的数字或者字符串,第二个参数radix是指定的转换的基数,介于236之间

因此需要对两个参数都进行校验,按照题目要求,需要对如果第一个参数不是数字的情况进行处理。

同时需要对radix进行处理,比如当前radix8,输入为9,就无法返回正确的数字,因为已经超出了进制转换的范围

同时要注意,parseInt的使用会从首位开始解析,如果第一位解析成功,第二位解析失败,则返回第一位的解析结果:

parseInt('5f');
// 5

parseInt('15', 2);
// 1

2 charCodeAt方法

通过charCodeAt方法返回指定位置的字符的Unicode编码

charAt()方法执行返回的是指定位置的字符子串。

3 Unicode编码

需要通过判断字符的Unicode编码来将字符串转换位数字,首先看一下常用的ASCII码:

几个关键的字符:

  • 0的编码是48,假设当前返回的字符串是'5',其Unicode编码是53, 那么将它转换为数字的话,就需要用其Unicode编码减去48,结果是5
  • A的编码是65,假设当前返回的字符串是'B',其Unicode编码是66, 那么将它转换为数字的话,就需要用其Unicode编码减去55,结果是11
  • a的编码是97,假设当前返回的字符串是'b',其Unicode编码是98, 那么将它转换为数字的话,就需要用其Unicode编码减去87,结果是11

最终的实现:

const parseInt2 = (s, radix = 10) = > {
  // 针对输入字符的处理
  if (typeof s !== 'string') {
    return NaN
  }

  // radix只能是[2, 32]的正整数
  if (typeof radix !== 'number' || radix > 32 || radix < 2 || !/^[0-9]+$/.test(String(radix))) {
    return NaN
  }

  let c;
  let result = 0;
  for (let i = 0; i < s.length; i++) {
    c = s.charCodeAt(i);

    if (c >= 97) { // 小写字母a转换为10
      c -= 87
    } else if (c >= 65) { // 大写字母A转换为10
      c -= 55
    } else { // 数字直接转换
      c -= 48
    }

    // 超出进制范围
    if (c >= radix) {
      // 如果第一位就出错返回NaN
      if (i === 0) {
        return NaN
      }
      // 非第一位出错,跳出循环,返回已解析的结果
      break;
    }

    // 进位求和
    result = (result * radix + c)
  }

  return result;
};

console.log(parseInt2('5A'));
console.log(parseInt('5A'))

嗯,基础太不扎实了

又尝试了一下使用reduce代替for循环实现,逻辑是相同的,只不过学到了如何提前结束reduce的方法,借助修改reduce遍历函数的第四个参数实现

const parseInt2 = (str, radix = 10) => {
  if (typeof str !== 'string') {
    return NaN;
  }
  
  if (typeof radix !== 'number' || radix > 32 || radix < 2 || !/^\d+$/.test(radix)) {
    r
    eturn NaN;
  }
  return [...str].reduce((total, current, currentIndex, array) => {
    let charCode = String(current).charCodeAt(0);
    if (charCode >= 97) {
      charCode -= 87
    } else if (charCode >= 65) {
      charCode -= 55
    } else {
      charCode -= 48
    }
    if (charCode >= radix) {
      if (currentIndex === 0) {
        return NaN
      }
      array.splice(currentIndex + 1);
      return total
    }
    total = total * radix + charCode;
    return total
  }, 0);
};
console.log(parseInt2('5123', 15));
console.log(parseInt('5123', 15))

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值