首页
/ freeCodeCamp Basic JavaScript 实战解读:Create Decimal Numbers with JavaScript(创建十进制小数变量)

freeCodeCamp Basic JavaScript 实战解读:Create Decimal Numbers with JavaScript(创建十进制小数变量)

2026-09-07 13:35:10作者:秋阔奎Evelyn

本篇围绕 freeCodeCamp 课程中 Basic JavaScript(基础 JavaScript)知识块里的《Create Decimal Numbers with JavaScript》练习展开,讲解如何在 JavaScript 变量中存储带小数部分的十进制数(浮点数)、题目隐藏的验证逻辑(typeof 与取模运算),并给出可直接运行的参考答案。结合本仓库 练习源文件课程结构配置,读者可同时掌握该题目的完整元数据格式、判题原理以及它在整个 JavaScript 课程中的知识定位。

一、挑战速览:题目长什么样

该练习在 freeCodeCamp 官方仓库中以 Markdown 文件承载,路径为:

curriculum/challenges/english/blocks/basic-javascript/cf1391c1c11feddfaeb4bdef.md

文件名使用其全局唯一的 idcf1391c1c11feddfaeb4bdef),这样同一道题在英文与各语言翻译目录间可以通过 id 一一对应,便于课程内容的同步翻译与维护。

从仓库中的结构文件可以看到,本题目在 Basic JavaScript 知识块中的前后顺序为:

顺序 题目 id 标题
上一个 56533eb9ac21ba0edf2244ad Decrement a Number with JavaScript
本题 cf1391c1c11feddfaeb4bdef Create Decimal Numbers with JavaScript
下一个 bd7993c9c69feddfaeb7bdef Multiply Two Decimals with JavaScript
再下一个 bd7993c9ca9feddfaeb7bdef Divide One Decimal by Another with JavaScript

题目位于算术运算系列的中段:在学会加减乘除、自增自减之后,开始接触“小数”,并紧接着进入小数的乘法与除法运算,属于一条连续、递进的技能线。整个 Basic JavaScript 块属于 javascript-algorithms-and-data-structures 超级块(superblock),见 superblock 结构文件

文件开头的元数据(frontmatter)

练习文件前 7 行是 YAML 格式的元数据,用于描述该挑战的登记信息:

---
id: cf1391c1c11feddfaeb4bdef
title: Create Decimal Numbers with JavaScript
challengeType: 1
forumTopicId: 16826
dashedName: create-decimal-numbers-with-javascript
---
  • id:挑战全局唯一标识符,同时作为文件名;
  • title:页面上显示的中文/英文标题;
  • challengeType:挑战类型编号。值为 1,对应 @freecodecamp/shared 的 challenge-types 定义中的 js(普通 JavaScript 代码题),意味着学习者在浏览器内置代码编辑器中直接编写并运行 JavaScript;
  • forumTopicId:关联的论坛讨论主题编号,用于在社区中追溯该题答疑帖;
  • dashedName:URL 化的短名称,全部小写并用连字符连接。

这些字段(idtitlechallengeTypedashedName 等)都要经过 challenge-schema.js 的 Joi 校验:例如 challengeType 必须是 0~33 之间的数字,dashedName 必须匹配 slug 正则,保证每道题结构化合法、可以被课程构建管线正常解析。

二、知识点:什么是“小数变量”

题目的 --description-- 部分用一句话点明核心概念:

我们可以把十进制小数(decimal numbers)存入变量中。小数有时也被称为**浮点数(floating point numbers)**或 float

也就是说,在 JavaScript 中不区分“整数变量”和“小数变量”,变量名只是值的容器,你给它赋什么类型的值它就是什么。赋值时带小数点的数字字面量即为浮点数:

const ourDecimal = 5.7;   // 浮点数:整数部分 5,小数部分 .7
const myDecimal = 5.7;    // 同样的赋值方式

还可以用科学计数法书写浮点数,例如 1.5e3 表示 15001.5e-3 表示 0.0015;去掉小数点的 5 就是整数。本练习刻意使用带小数部分的值(如 5.7),目的是让学习者分清“整数字面量”与“浮点字面量”在赋值语义上的区别。

有限精度与浮点运算的注意点

题目在 --description-- 中特别附加了一条重要的工程性提示

当你对数字进行运算时,它们是以**有限精度(finite precision)**被计算的。基于浮点数进行的运算,其结果可能与你预期的结果不同。

这正是所有基于 IEEE 754 双精度浮点实现的语言(JavaScript 也不例外)的共性现象。例如在控制台里尝试:

0.1 + 0.2;   // 实际得到 0.30000000000000004,而非精确的 0.3

原因在于 0.10.2 这类十进制小数无法在二进制浮点体系中被精确表示,只能取最接近的近似值,多次运算后近似误差就会被放大。因此:

  • 需要精确比较金额等敏感数据时,应避免直接比较浮点结果,可引入误差阈值(如 Math.abs(a - b) < 1e-9)或使用整数化的最小货币单位(分);
  • 题目原文建议:若在实际编程中遇到这类“反直觉结果”,可以到 freeCodeCamp 论坛的相关主题帖中提问(对应元数据中的 forumTopicId)。

这条提示属于工程经验,本练习题先让学习者建立“浮点数的结果不一定精确”的直觉,为后续更复杂的数值计算题做铺垫。

三、题目要求:创建你的第一个小数变量

--instructions-- 明确了两点任务:

创建一个名为 myDecimal 的变量,并赋给它一个带小数部分的十进制值(例如 5.7)。

给定的种子代码(--seed--)如下:

const ourDecimal = 5.7;

// Only change code below this line

其中:

  • 示例变量 ourDecimal = 5.7 仅供演示,不要修改,因为隐藏测试会基于原始种子内容进行比对;
  • 学习者只需在注释下方补写一行声明即可。

一个最常见的写法是:

const myDecimal = 9.9;

它同时满足题目给出的参考答案(见仓库文件的 --solutions-- 段):

const myDecimal = 9.9;

补充说明两点容易踩的坑:

  1. 别忘了 const 声明的变量在声明时必须初始化,const myDecimal; 会直接抛语法错误;
  2. 赋值 5.7 还是 9.9 并不影响判分,只要值带小数部分即可——判题只做“类型”与“是否为小数”两项结构检查,这正是下面要讲的隐藏测试逻辑。

四、判题逻辑拆解:两项隐藏测试如何工作

--hints-- 段定义了本题的判定条件,freeCodeCamp 的运行环境会将种子代码与学习者代码拼接后,在浏览器沙箱中逐条执行下面的断言:

assert(typeof myDecimal === 'number');

测试一:myDecimal 是一个数字(number 类型)

typeof 返回值的类型字符串。因为小数在 JS 中仍属于 number 类型(并不存在单独的 float 类型),所以只要变量被赋了数字字面量,该断言即通过。若学习者误写为 const myDecimal = "9.9";(字符串),typeof 返回 "string",此测试立刻失败。

assert(myDecimal % 1 != 0);

测试二:myDecimal 带有小数部分

这是本题最有教学价值的一行:它利用 JavaScript 的**取模运算符(%)**来判断“是否有小数部分”。

  • 对任意整数 nn % 1 恒等于 0(如 9 % 1 === 0);
  • 对任意带小数部分的数 xx % 1 会得到其余数(如 9.9 % 1 === 0.95.7 % 1 === 0.7),结果不等于 0

因此只要 myDecimal % 1 != 0 成立,就能确认该值确实“带小数点”,有效防止学习者用整数(如 9)或 1e3 这类无小数结果蒙混过关。这也是教材中常用的“整数性检测”技巧(等价写法为 myDecimal % 1 !== 0)。

小提示:在真实工程中判断“是否为整数”,更推荐的写法是 Number.isInteger(value);而 x % 1 !== 0 作为一种极简手写方案,仍然在很多面试与算法题里出现。本题借此让学习者第一次接触取模与整除的概念,为后续的 Finding a Remainder in JavaScript 系列题目埋下伏笔。

五、这道题在课程体系中的衔接关系

知识块结构文件的挑战顺序可以看出设计者的编排思路:

  1. 变量基础:先学习声明变量、赋值、初始化(var/let/const);
  2. 整数算术:加、减、乘、除、自增、自减——全部使用整数字面量;
  3. 引入浮点数(本题):把数值类型从整数扩展到小数,并提示精度问题;
  4. 浮点算术:紧接着的 “Multiply Two Decimals with JavaScript” 与 “Divide One Decimal by Another with JavaScript” 两道题,练习小数之间的乘法与除法;
  5. 随后进入取余、复合赋值、字符串与数字转换等更复杂的主题。

如果逐题作答,会发现该块内每个练习文件都遵循完全一致的段落格式:--description--(讲解)→ --instructions--(任务)→ --hints--(隐藏测试说明)→ --seed--(初始代码)→ --solutions--(官方参考实现)。学习者在界面上看不到的只有 --solutions--(防止直接抄答案),其余段落都以友好方式渲染为题目卡片。

六、如何本地查看与运行这道题

  • 阅读题目与元数据:直接打开 cf1391c1c11feddfaeb4bdef.md,即可逐段阅读该题的全部内容;
  • 查看课程结构:该题在块中的位置见 basic-javascript.json;块所属的超级块(证书路径)见 javascript-algorithms-and-data-structures.json
  • 了解挑战类型定义challengeType: 1 的确切含义(JS 代码挑战)见 challenge-types.ts
  • 本地实验:在任意支持 ES6 的浏览器控制台或 Node.js 环境(运行 node 后逐行输入)中执行 const myDecimal = 9.9; 后再跑两条断言,即可自行验证:
    const myDecimal = 9.9;
    console.log(typeof myDecimal === 'number'); // true
    console.log(myDecimal % 1 != 0);            // true
    
    若把值换成整数 9,第二条会输出 false,直观体会取模检测的判定逻辑。

小结

Create Decimal Numbers with JavaScript 虽然只是一道短小的入门练习,却承担了三个目标:让学习者掌握“小数(浮点)可直接存入变量”的语法事实、建立对浮点有限精度这一工程特性的初步认知,并通过 typeofx % 1 两项隐藏断言理解“测试驱动完成练习”的机制。结合本仓库中该题的完整 Markdown 源文件、知识块顺序与 schema 校验规则,你也可以把同样的解析方法迁移到 Basic JavaScript 块内任意一道练习题上,快速读懂每一道题的目标、边界条件与官方答案。

登录后查看全文
热门项目推荐
相关项目推荐