12 行代码跑通 freeCodeCamp 的 Profile Lookup:对象数组查找与括号属性访问
2026/9/10 16:50:19 网站建设 项目流程

12 行代码跑通 freeCodeCamp 的 Profile Lookup:对象数组查找与括号属性访问

【免费下载链接】TVBoxOSCTVBoxOSC - 一个基于第三方项目的代码库,用于电视盒子的控制和管理。项目地址: https://gitcode.com/GitHub_Trending/tv/TVBoxOSC

在 freeCodeCamp 的 Profile Lookup 挑战里,你要按姓名在对象数组里查联系人,并返回他的某个属性。可如果凭直觉写,lookUpProfile("Akira", "likes")完全可能返回undefined。本文用这道对象数组查找题,讲清括号属性访问的用法、两种缺失语义的处理,12 行代码全部讲透——适合正在刷 JS 基础练习、又被这类函数题卡住的你。

先查人、再查属性:把题面翻译成判定表

函数签名是固定的:lookUpProfile(name, prop)name是名字字符串,prop是属性名字符串。被查询的数据是contacts对象数组,每个元素代表一个人:

const contacts = [ { firstName: "Akira", lastName: "Laine", number: "0543236543", likes: ["Pizza", "Coding"] }, { firstName: "Kristian", lastName: "Vos", number: "unknown", likes: ["JavaScript", "Gaming"] }, // ... 其余两个略 ]; function lookUpProfile(name, prop) { // Only change code below this line }

注意字段是异构的:number是字符串,likes是数组,各对象拥有的属性集合也不完全一样。判定逻辑由此拆成三条分支:

  • 成功分支:某个联系人的firstNamename相等,且prop确实是这个对象的属性 → 原样返回该属性的值,字符串就返回字符串,数组就返回数组。
  • 失败分支 A(缺人):整个数组里没有任何firstName匹配name→ 返回"No such contact",此时prop是否合法都不重要。
  • 失败分支 B(缺属性):人找到了,但prop不在那个对象上 → 返回"No such property"

关键在后半句:两种失败语义不同,优先级固定。先判人,人查不到就直接报"缺人";人命中之后才轮到判属性。顺序一颠倒,lookUpProfile("Bob", "potato")就会被判成"属性不存在",而官方预期是"人不存在"。

两种写法一次讲透:官方短路与显式检查

官方版:for...in 加 ||

freeCodeCamp 的参考答案用for...in遍历下标,再用一个||兜底:

function lookUpProfile(name, prop) { for (let i in contacts) { // i 依次取 "0"、"1"、"2"、"3" if (contacts[i].firstName === name) { // 括号访问读取 prop 指向的属性,取不到就用 || 兜底 return contacts[i][prop] || "No such property"; } } // 整轮遍历没命中,才说明这个人不在数组里 return "No such contact"; }

为什么return "No such contact"要放在循环外面?因为必须把整个数组走完、firstName一个都没对上,才能下结论"人不在通讯录里";若第一个对象没匹配就报缺人,等于把后面的数据全部误判为不存在。而一旦命中就立刻return,"先查人、后查属性"的顺序天然被保住。这里用到的括号属性访问,就是obj[key]key为变量时的读法——prop是运行时传进来的键名,只有括号语法才能解释它。

⚠️边界提示contacts[i][prop]在属性不存在时读到undefined||顺势换成提示语。可当合法值本身就是假值——比如age: 0flag: false、空字符串——||会把正常返回值一并吞掉,误报 "No such property"。官方测试数据里恰好都是真值,所以能过,但这个隐患是真实存在的。

更稳的版本:for...of 加 hasOwnProperty

function lookUpProfile(name, prop) { for (const contact of contacts) { if (contact.firstName === name) { // 只问"属性在不在",不问"值是不是真值" if (Object.prototype.hasOwnProperty.call(contact, prop)) { return contact[prop]; // 0、false、空串都原样返回 } return "No such property"; } } return "No such contact"; }

与官方版相比只有两处差异:直接遍历对象本体而不是下标,以及把||捷径换成一次显式的hasOwnProperty.call检查。hasOwnProperty(判断对象是否拥有某个自有属性)只关心"在不在",不关心"值真假",于是age: 0这类假值会被如实返回 0,而官方版会把它误报成"缺属性"。两者都能通过全部官方断言,但后一种在语义上更诚实。

四个高频错误:错误代码改正确代码

  • 点语法取属性contact.propcontact[prop]。点语法读的是字面键"prop",永远是undefined;变量只能经括号解释为键名。
  • 判空顺序写反:先查prop是否合法再找人 → 人命中之后才查prop。否则lookUpProfile("Bob", "potato")会错报 "No such property"。
  • 对整数组做统一 prop 校验:拿prop去挨个校验所有联系人 → 只对命中的那个对象校验。字段各不一致,有效性只能以实际匹配到的对象为准。
  • 把 likes 拼成字符串contact.likes.join(", ")contact.likes。断言校验返回值是数组,join 一转成字符串就挂了。

在 freeCodeCamp 仓库里验证它 🔍

挑战文件curriculum/challenges/english/blocks/basic-javascript/5688e62ea601b2482ff8422b.md的 front-matter 记录了challengeType: 1(浏览器控制台函数题)与dashedName: profile-lookup。其中的--hints--段落就是断言脚本:在线编辑器运行时,它会拿你的补全函数逐条执行 assert;--seed-contents--段落则是你在编辑器里看到的初始代码,只有注释标出的区域开放编辑。

回到自己的控制台验证

  • ||换成hasOwnProperty.call,再跑一遍全部六条断言,确认行为一致。
  • 手工给 contacts 加一个number: 0的联系人,分别调用两种写法,看一个返回 "No such property"、另一个返回 0。
  • contacts.find(c => c.firstName === name)加可选链重写循环,体验函数式风格。

现在就把这道题做掉,然后到空文件里手写本文的三种版本——当你能说清每个版本会吞掉哪些假值时,这道题才算真正属于你。

【免费下载链接】TVBoxOSCTVBoxOSC - 一个基于第三方项目的代码库,用于电视盒子的控制和管理。项目地址: https://gitcode.com/GitHub_Trending/tv/TVBoxOSC

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询