为什么在JavaScript中['1', '5', '11'].map(parseInt) 返回 [1, NaN, 3]

他接下来看到的东西震惊了他:

9d7ee9acfb8c2a970c9f304510c73381.png

这怎么可能呢?parseInt是不是坏了? map() 是不是有bug?

他惊慌地抬头看,引来了Jake尖锐而令人不安的笑声。

Alex自称编程高手,以快速编码和简洁代码为傲。

尽管刚进入这个行业不久,他总是认为自己比团队其他人都强,固执地我行我素;所有善意的建议都被他当耳边风。

但Alex很快就要遭遇灾难性的失败了。这将是一次痛苦而令人谦卑的经历,他永远不会忘记。

一切都始于Alex和Cody被分配了一个项目任务。要让用户查看团队一直在开发的电子商务网站上的产品。

他们仍处于创业阶段,所有数据都存储和更新在CSV文件中。

产品名称、价格、数量...所有你在亚马逊等网站上能看到的常见信息。

当Alex得知要合作时,他傲慢地嗤之以鼻。

"我不需要和任何人合作,好吗?"他一边在电脑上打字,一边对善良的工程主管Jake冷笑道。"这简直就是从数据库获取数据然后在JSX中显示而已"。

"Alex,你需要学会与他人合作,我一直在告诉你这一点。"Jake带着耐心而勉强的微笑回应道。他已经习惯了这个人自我中心的行为。

"我不需要和任何人合作,我自己就能搞定。Cody只会用他那些关于可读性代码的废话拖我后腿。"

"Cody是我们最优秀的员工之一,他花时间是有原因的。我一直在告诉你,编码并不只是快速或简洁地写代码..."

"你总是对我说教,但你从不听我的。这次我只想一个人工作,行吗?" "拜托?"Alex迅速补充道,以避免听起来太粗鲁 - 当然,脸上仍带着那种傲慢的笑容。

Jake叹了口气。

"好吧,如果你能将这个字符串数组转换成相同的数字数组,我就让你一个人工作。"他一边说一边在旁边的纸上写道。

Alex简直不敢相信。纸上是一个简单的数组。

['1', '5', '11']

这一定是个陷阱问题。他怀疑地抬头看着Jake。

"认真的吗?你觉得我蠢到连这个都解析不了吗?"

"试试看,你只有一次机会。"Jake对这个年轻人表现出惊人的耐心,他应该得到一枚自制力勋章。

Alex带着得意的表情,打开了一个新的VS Code终端,傲慢地输入了看似显而易见的Node解决方案:

['1', '5', '11'].map(parseInt)

他得意洋洋地笑了,转身却看到Jake脸上带着了然的微笑 - 他立刻失去了平衡。

"你确定吗Alex?为什么不按Enter键,让我们看看实际的结果数组是什么。"

有点不确定的他,在最后时刻扫视了一遍简短的CLI代码以确保万无一失。

他接下来看到的东西震惊了他的内心。

003e2d67e46ded570040ef3fb9a98c06.png

这怎么可能呢? parseInt 是不是坏了? map() 是不是有bug?

他惊慌地抬头看,引来了Jake尖锐而令人不安的笑声。

"Alex,你被解雇了。"

"什么?!"Alex尖叫道。

"在我闭上眼睛又睁开之前收拾东西滚出去,你这个傲慢的蠢货!"

你看,Alex的失败并不是因为他不理解 mapparseInt -- 尽管理解它们本可以帮到他。

而是因为他痴迷于使代码尽可能简短,以牺牲可读性和清晰度为代价...

事实上,在99%的情况下,我们是这样使用 mapparseInt 的:

const doubles = ['1', '5', '11'].map((num) => num * 2);

console.log(doubles); // [2, 10, 22]

const num = parseInt('5');

console.log(num); // 👍 5 -- not NaN!

但是当你使用 mapconsole.log 时,你可能会对结果感到震惊:

const doubles = ['1', '2', '3'].map(console.log);

它为每个项目记录了3对数字!

981aa530d2c7d7dc80c0d730df57ad0b.png

这是因为 map() 回调实际上接受3个参数:

42530d446810e24727e7fe88d9308368.png

所以你实际上是用3个参数调用 parseInt :

// parseInt take 2 args max but JS compiler doesn't complain
['1', '5', '11'].map(parseInt)

// parseInt('1', '0', ['1', '5', '11'])
// parseInt('5', '1', ['1', '5', '11'])
// parseInt('11', '2', ['1', '5', '11'])

Alex从不知道 parseInt 接受1个或2个参数,并且对每种情况的行为都不同:

当有第二个参数时,它成为第一个数字参数的基数:

// 👎 invalid positive number, ignore
parseInt('1', '0'); // 1 ✅
parseInt('3', 'blah blah'); // 3

// 👎 invalid base (1)
parseInt('2', '1'); // NaN
parseInt('5', '1'); // NaN ✅

// 👎 '10' is 2 in base 2 (remember?)
parseInt('10', '2'); // 2
parseInt('11', '2'); // 3 ✅

尽管他对 map 和 parseInt 的知识一般,但只要更加明确,他本可以避免所有这些问题:

['1', '5', '11'].map((num) => parseInt(num));

缩短代码可能有利于减少混乱,但我们应该始终优先考虑清晰和可读的代码:

特别是当增加的长度并不是什么大问题时,你知道吗?

async function setTimeout() {
  // ❌
  await new Promise((resolve) => setTimeout(resolve, 1000));
  console.log('Coding Beauty');
}

async function setTimeout() {
  // ✅
  await new Promise((resolve) => setTimeout(() => resolve(), 1000));
  console.log('Coding Beauty');
}

最后:

CSS技巧与案例详解

vue2与vue3技巧合集

VueUse源码解读

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@大迁世界

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值