freeCodeCamp Profile Lookup 挑战:3 步写出零失误的通讯录查找函数
【免费下载链接】TVBoxOSCTVBoxOSC - 一个基于第三方项目的代码库,用于电视盒子的控制和管理。项目地址: https://gitcode.com/GitHub_Trending/tv/TVBoxOSC
freeCodeCamp 仓库的 basic-javascript 模块里有一道 JavaScript 挑战叫 Profile Lookup(资料卡查询)。它表面上只是让你补一个函数,却用不到 15 行代码压进四个考点:for 循环遍历、运行时属性名取值、判定优先级和返回值类型保持。这是典型的组合考点题。
先把题面用大白话读一遍
你会收到两个输入:name(一个名字)和 prop(以字符串传进来的属性名)。contacts 数组是一本写好的通讯录,每一项是一个人。你的任务:找到 firstName 与 name 匹配的那个人,返回他 prop 属性的值。
麻烦在两条报错分支:人没找到,返回 "No such contact";人找到了但他没有这个属性,返回 "No such property"。注意优先级——先查人,找到人才谈查属性。哪怕人不在通讯录、属性名也根本不存在,只报 "No such contact"。
| 判断顺序 | 命中条件 | 返回值 |
|---|---|---|
| 1 | 整个数组里找不到 firstName 匹配的联系人 | "No such contact" |
| 2 | 人找到了,但 prop 不是他的属性 | "No such property" |
| 3 | 人和属性都命中 | 该属性的原值(可能是字符串,也可能是数组) |
题目给的初始代码如下,数据做了精简:
const contacts = [ { firstName: "Akira", lastName: "Laine", number: "0543236543", likes: ["Pizza", "Coding", "Brownie Points"], }, // ……还有两个人,结构相同 ]; function lookUpProfile(name, prop) { // 在这里补全函数体 }看数据能发现两条线索:每人的字段类型并不完全一样(likes 是数组,number 是字符串),而且 prop 是个变量,不是固定键名。
动手之前先想清楚这三个问题
第一,prop 是一个装着属性名的字符串,你要动态读取"那个键名"对应的值,该写什么语法?
第二,返回值可能是字符串、可能是数组、还可能是报错文案,怎么保证返回的东西和原始值类型一致,不被你顺手转换掉?
第三,人和属性都无效时,该报哪条错?判定顺序写反了,会撞断言。
💡 这三个问题就是这道题的三个坑。先记在脑子里,写完代码再回来逐条验证。
先写第一版,再看它卡在 || 的边界上
最直觉的写法,其实能过全部官方断言:
function lookUpProfile(name, prop) { for (let i in contacts) { if (contacts[i].firstName === name) { return contacts[i][prop] || "No such property"; } } return "No such contact"; }for...in(按键名遍历,用在数组上拿到的其实是下标)在这里挨个过每个人,取值用方括号 contacts[i][prop],人没找到就在循环结束后兜底 "No such contact"。
问题出在||上:如果某个属性值恰好是假值(空字符串、0、false、null),它会被当成"没有这个属性",直接替换成报错文案。当前测试数据里没有这种属性,所以测试能过,但逻辑埋了雷。
想改,是因为要把"属性存不存在"和"属性值真不真"彻底解耦:用 hasOwnProperty(判断对象自身是否拥有某个属性的方法)做显式检查,而不是靠 || 的短路副作用:
function lookUpProfile(name, prop) { for (const contact of contacts) { if (contact.firstName === name) { if (Object.prototype.hasOwnProperty.call(contact, prop)) { return contact[prop]; } return "No such property"; } } return "No such contact"; }for...of 直接遍历数组元素,不用绕下标,意图更直白。name 一命中,先用 hasOwnProperty 查属性:存在就原样返回原值(哪怕它是假值,也不误判),不存在才回 "No such property"。判定顺序不变:整个人都找不到,才会走到最后一行报 "No such contact"。
这三种写法最容易翻车,对照你自己的代码
⚠️ 错法一,用点语法取值:
return contact.prop;错在哪:点号读到的是字面键 "prop",而不是变量 prop 里装的属性名,结果永远是 undefined。纠正:改用方括号 contact[prop]。
错法二,先判属性再判人:
for (const contact of contacts) { if (!(prop in contact)) return "No such property"; if (contact.firstName === name) return contact[prop]; }错在哪:name 和 prop 都无效时,断言要 "No such contact",这样却先报了 "No such property"。纠正:把 name 的查找完整做完,找到人再谈 prop。
错法三,把数组拼成字符串:
return contact[prop].join(", ");错在哪:官方断言用 deepEqual(逐元素比较两个数组是否相等)校验,要求 likes 数组原样返回,一 join 就变字符串,必挂。纠正:属性值直接返回,不做任何转换。
写完之后,顺手把仓库里这两个文件读掉
这道题把四个知识点压进了一个函数:对象数组遍历、运行时属性名的安全取值、固定的判定优先级、返回值类型保持。先读判定顺序,再用 for...of 加 hasOwnProperty 落地,最后过一遍错题本——三步走完,断言全绿。
想核对完整题面和六条断言,看 curriculum/challenges/english/blocks/basic-javascript/5688e62ea601b2482ff8422b.md;想确认它在课程里的坐标,翻 curriculum/structure/blocks/basic-javascript.json。能独立写出来后,就去挑战它的 Lab 版 Build a Profile Lookup——那关要你从零搭一个完整的查找小工具,才是这道题真正的下一站。
【免费下载链接】TVBoxOSCTVBoxOSC - 一个基于第三方项目的代码库,用于电视盒子的控制和管理。项目地址: https://gitcode.com/GitHub_Trending/tv/TVBoxOSC
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考