首页
/ freeCodeCamp Basic JavaScript 挑战精讲:用点号与方括号访问嵌套对象(Accessing Nested Objects)

freeCodeCamp Basic JavaScript 挑战精讲:用点号与方括号访问嵌套对象(Accessing Nested Objects)

2026-09-07 22:01:01作者:尤辰城Agatha

导读

本篇文章以 freeCodeCamp 开源课程中 Basic JavaScript(基础 JavaScript)模块的 "Accessing Nested Objects" 挑战为讲解主线,完整剖析 JavaScript 中嵌套对象的访问规则、点号与方括号两种语法的适用边界,并手把手拆解该挑战的初始代码、隐藏测试断言与标准解法。读完本文,你将不仅能独立通过这道题,还能理解 freeCodeCamp 挑战文件从 descriptionhintsseedsolutions 的完整组织结构,把“做题”上升为“读懂课程源码”。该挑战位于本仓库的 curriculum/challenges/english/blocks/basic-javascript/56533eb9ac21ba0edf2244cc.md,属于 JavaScript 对象体系“从入门到精通”序列中的一环。

一、挑战定位:Basic JavaScript 对象模块中的关键一环

本挑战的文件名 56533eb9ac21ba0edf2244cc.md 位于 curriculum/challenges/english/blocks/basic-javascript/ 目录,其中 basic-javascript 即“块”(Block)名。在同一块的课程顺序文件 curriculum/structure/blocks/basic-javascript.json 中,可以看到它前后依次排布着紧密衔接的知识点:

  • Accessing Object Properties with Dot Notation(点号访问对象属性)
  • Accessing Object Properties with Bracket Notation(方括号访问对象属性)
  • Accessing Object Properties with Variables(用变量访问对象属性)
  • Updating Object PropertiesAdd New PropertiesDelete Properties
  • Manipulating Complex Objects(操作复杂对象)
  • Accessing Nested Objects(本挑战)
  • Accessing Nested Arrays(访问嵌套数组)
  • Record Collection(记录集合综合练习)

也就是说,本挑战是在掌握点号与方括号基础语法之后,把二者“链接”起来处理多层对象结构的综合演练,是通向 Record Collection 这类综合性项目的必经之路。

二、核心概念:什么是嵌套对象

在 JavaScript 中,对象属性的值可以是任意类型——包括另一个对象。当一个对象的属性值本身还是对象(甚至可以继续向下嵌套若干层)时,就构成了“嵌套对象(Nested Object)”。

例如挑战描述中给出的示例 ourStorage

const ourStorage = {
  "desk": {
    "drawer": "stapler"
  },
  "cabinet": {
    "top drawer": {
      "folder1": "a file",
      "folder2": "secrets"
    },
    "bottom drawer": "soda"
  }
};

这里共有三层结构:

  • 顶层是 deskcabinet 两个属性;
  • cabinet 的值又是一个对象,内部含 "top drawer""bottom drawer"
  • "top drawer" 的值仍是对象,内部含 folder1folder2

访问子属性的方式,就是把点号或方括号逐层“链接”起来,这正是挑战标题与描述的核心:sub-properties of objects can be accessed by chaining together the dot or bracket notation(对象子属性可以通过链式串联点号或方括号来访问)。

三、规则要点:点号与方括号,何时用哪个

要正确解答本挑战,必须先吃透两种访问语法的取舍规则,这也是官方 hints(隐藏测试)所要校验的核心。

3.1 点号记法(Dot Notation)

点号语法适用于符合 JavaScript 合法标识符命名规则的属性名,即名称只能包含字母、数字、下划线(_)与美元符($),且不能以数字开头,也不能包含空格。

ourStorage.desk.drawer;    // "stapler"

3.2 方括号记法(Bracket Notation)

当属性名不符合标识符规则时——比如带空格(如 "top drawer""glove box")、以数字开头,或需要由变量动态计算时——必须使用字符串形式的方括号记法。挑战示例就同时用到了两种写法:

ourStorage.cabinet["top drawer"].folder2;   // "secrets"
ourStorage.desk.drawer;                     // "stapler"

注意 "top drawer" 必须写在方括号并加引号中,因为 ourStorage.cabinet.top drawer 这种写法在语法上根本无法成立(空格会破坏标识符)。

3.3 混合链式的取值推演

示例表达式逐步求值如下:

  • ourStorage.cabinet → 得到 cabinet 子对象;
  • ourStorage.cabinet["top drawer"] → 得到 folder1/folder2 子对象;
  • ourStorage.cabinet["top drawer"].folder2 → 得到字符串 "secrets"
  • ourStorage.desk.drawer → 一路点号下钻,得到 "stapler"

挑战原文据此断言:ourStorage.cabinet["top drawer"].folder2 求值结果是字符串 secretsourStorage.desk.drawer 求值结果是字符串 stapler。可见**“链式访问”的求值顺序是从最外层对象开始,一层一层向内取属性值**,每一步的返回值都是下一步的访问目标。

四、本关任务拆解:读取 myStorage 中的手套箱

在掌握上述规则后,我们来看本关的实际任务(instructions):

Access the myStorage object and assign the contents of the glove box property to the gloveBoxContents variable. Use dot notation for all properties where possible, otherwise use bracket notation.

翻译过来即:从 myStorage 对象中取到 glove box 属性的内容,赋值给变量 gloveBoxContents能使用点号的地方必须用点号,实在无法使用点号时再用方括号

4.1 初始代码(seed)

挑战为学习者预置了如下初始代码:

const myStorage = {
  "car": {
    "inside": {
      "glove box": "maps",
      "passenger seat": "crumbs"
     },
    "outside": {
      "trunk": "jack"
    }
  }
};

const gloveBoxContents = undefined;

myStorage 的结构为三层:顶层 car → 中层 inside(还有并列的 outside)→ 内层 "glove box""passenger seat"。初始代码把 gloveBoxContents 置为 undefined,等待学习者用正确的链式访问替换。

4.2 求解思路

逐层分析 glove box 的访问路径:

  1. 取顶层 myStorage.car —— car 是合法标识符,必须用点号
  2. 取中层 myStorage.car.inside —— inside 是合法标识符,必须用点号
  3. 取内层 myStorage.car.inside["glove box"] —— "glove box" 含空格,无法用点号,必须用方括号字符串

于是标准解为:

const myStorage = {
  "car": {
    "inside": {
      "glove box": "maps",
      "passenger seat": "crumbs"
    },
    "outside": {
      "trunk": "jack"
    }
  }
};

const gloveBoxContents = myStorage.car.inside["glove box"];

gloveBoxContents 最终将等于字符串 "maps"。若写错顺序(如 myStorage.car["glove box"].inside)则无法命中目标属性;若对 "glove box" 误用点号(myStorage.car.inside.glove box)则直接产生语法错误。

五、隐藏测试解析:仓库如何判定你的代码是否正确

freeCodeCamp 的每道挑战都附有 # --hints-- 段,由框架自动运行断言(assert)来打分。读懂它们,等于拿到官方评分标准。本挑战共有 4 个 hint,全部定义在挑战文件 curriculum/challenges/english/blocks/basic-javascript/56533eb9ac21ba0edf2244cc.md 中。

5.1 取值正确性

assert(gloveBoxContents === 'maps');

要求 gloveBoxContents 严格等于字符串 maps。它直接验证了你访问路径的终点是否真的指向 "glove box" 的值。

5.2 语法规范性(能点号必点号)

assert.match(code, /myStorage\.car\.inside/);

该断言用正则匹配源码文本,检查代码中是否出现了 myStorage.car.inside 这一段点号链。这就在机制上强制你遵守“where possible 尽量用点号”的指令——只要这两层没写对(例如不必要地写成 myStorage["car"]["inside"]),即使最终结果正确,本题也会判错。

5.3 变量声明方式

assert.match(code, /const\s+gloveBoxContents\s*=/);

要求 gloveBoxContents 必须使用 const 声明(不允许改写为 letvar)。

5.4 原对象不得改动

const expectedMyStorage = {
  "car":{
    "inside":{
      "glove box":"maps",
      "passenger seat":"crumbs"
    },
    "outside":{
      "trunk":"jack"
    }
  }
};
assert.deepStrictEqual(myStorage, expectedMyStorage);

使用 deepStrictEqual 做深比较,确保初始的 myStorage 对象未被任何方式改动——这意味着你不能为了“取巧”而重写或扁平化对象。

从这些断言可以直观体会到 freeCodeCamp 的评测策略:既要结果正确,也要写法符合教学规范,还保护了初始数据不可篡改。这也是其课程“循序渐进约束练习者行为”的典型体现。

六、源码视角:挑战文件是怎么被解析、校验与执行的

作为一个开源项目,本仓库不仅提供课程文本,还提供一整套解析、校验与执行的实现。理解了这些,你就能从“做题者”升级为“课程研究者”。

6.1 frontmatter 元数据

每个挑战 Markdown 顶部是 YAML frontmatter,本挑战字段如下:

字段 含义
id 56533eb9ac21ba0edf2244cc 全局唯一挑战 ID,是课程排序、URL 与引用的主键
title Accessing Nested Objects 挑战显示标题
challengeType 1 挑战类型,从 packages/shared/src/config/challenge-types.ts 中维护的枚举顺序看,1 对应基础 JavaScript 编程练习类型(可运行 JS 代码并接受评测)
dashedName accessing-nested-objects URL 友好名称,同时受 schema 校验约束

课程结构文件 curriculum/structure/blocks/basic-javascript.json 正是按 id + title 的形式,以数组顺序记录块内全部挑战,而本挑战 id 56533eb9ac21ba0edf2244cc 恰好出现在该 JSON 的第 375 行前后,前后就是上文提到的那一整套对象练习。

6.2 Schema 校验

挑战文件必须满足 curriculum/schema/challenge-schema.js 中定义的 Joi 约束,例如 challengeType 必须是 0~33 的数字、dashedName 必须匹配 ^[a-z0-9-]+$solutions 必须是文件对象数组的数组等。其中 description 段是必填字符串,solutions(标准答案)则保存为多个文件快照,供后续测试运行与“显示解决方案”功能使用。

6.3 加载与构建链路

课程文件由 curriculum/src/get-challenges.ts 等加载器读取,随后在构建阶段(见 curriculum/src/build-superblock.ts 第 248 行附近)会检测 challenge.solutions?.length,并把解决方案中的源码文件转换成 polyvinyl 格式供测试运行器使用;文件级结构定义见 curriculum/src/file-handler.ts(其中声明了 solutions?: ChallengeFile[][])。也就是说,你在题解区看到的官方答案,本质上就是该 Markdown # --solutions-- 段被解析、校验并通过构建管线喂给评测系统的产物。

七、常见错误与调试建议

结合题目 hints 与教学意图,罗列本关最易出现的三类错误:

  1. 对含空格的键误用点号:如 myStorage.car.inside.glove box,会直接触发语法错误。空格键名只能写成 ["glove box"]
  2. 能点号却用方括号:如 myStorage["car"]["inside"],虽然结果正确,但会因不满足正则断言 /myStorage\.car\.inside/ 而无法通过 hint 2。
  3. 改动初始对象或漏写 const:重排对象结构会触发 deepStrictEqual 失败;把 const 改成 let/var 则会触发 hint 3 失败。

自查清单:结果是否为字符串 maps?访问链是否同时含点号段 myStorage.car.inside 与方括号段 ["glove box"]?声明是否为 const gloveBoxContents = ...myStorage 是否保持原样?

八、向后续挑战延伸

本挑战是“复杂结构访问”的起点。同一块中紧随其后的 Accessing Nested Arrays 会教你如何在对象与数组交错的结构中继续用链式下标定位元素;而 Record Collection 则要求综合运用“读取 + 更新 + 新增 + 删除”能力维护一个多层记录集合。掌握本挑战的“能点号则点号、否则方括号、逐层下钻”方法论后,再复杂的 JSON/对象结构你都能抽丝剥茧地访问到位。

结语

通过“Accessing Nested Objects”这一挑战,你同时获得了两层收获:作为学习者,你掌握了 JavaScript 嵌套对象链式访问的完整规则与点号/方括号的选择标准;作为开源课程读者,你看到了 freeCodeCamp 如何用 descriptioninstructionshintsseedsolutions 五段式结构,把“知识讲解 + 语法规约 + 自动化断言 + 起始代码 + 官方答案”封装成一份可版本化管理、可校验、可离线运行的挑战文件。现在,你可以打开 curriculum/challenges/english/blocks/basic-javascript/56533eb9ac21ba0edf2244cc.md 亲自重读原文,并在自己的编辑器中运行上面的示例与解法,亲手验证每一个取值结果。

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

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
594
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
916
1.83 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.58 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.01 K
516
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
388