如何使用JavaScript reduce方法从对象数组提取name值生成新数组
用reduce提取数组所有name字段值的实现方案
原始测试数组
const names = [ { name: 'Anna' }, { num: 27 }, { name: 'Valeria', age: 20}, { secondname: 'Wilson' }, { age: 12, name: 'Max' }, { weight:'50kg', height: '172cm', name: 'Nick' } ]
需求:基于上述数组,通过reduce方法生成新数组,包含原数组中所有对象的name字段值。
原有写法的错误原因
- 第一种写法:使用
+运算符合并累加值和name属性,初始累加值是数组,和字符串做+运算时会被隐式转换为字符串,最终得到字符串结果而非数组;同时未判断对象是否存在name字段,无该字段的项会拼接出undefined。// 错误示例 let allNames = names.reduce((previousValue, names) =>{ return previousValue + names.name},[]) console.log(allNames) - 第二种写法:存在语法问题,回调函数参数未定义、操作的
allName变量未声明、遍历项ar不存在,最后打印的是原数组而非结果,同样缺少name字段的存在性校验。// 错误示例 allName.push(ar.name); return allName; }, []); console.log(names);
正确实现代码
累加器初始值设置为空数组,遍历每一项时先校验是否存在name属性,存在就将属性值推入累加数组,遍历完成后返回的累加数组就是目标结果:
const allNames = names.reduce((acc, cur) => { // 校验当前项存在name属性时才加入结果,避免出现undefined if ('name' in cur) { acc.push(cur.name) } return acc }, []) console.log(allNames) // 输出结果:['Anna', 'Valeria', 'Max', 'Nick']
如果不需要兼容极老的运行环境,也可以用Object.hasOwn(cur, 'name')做属性校验,判断逻辑更严谨,避免原型链上的属性干扰。
如果不需要过滤假值、确定所有带name字段的项的值都是有效非假值,也可以写简化版本:
const allNames = names.reduce((acc, cur) => cur.name ? acc.concat(cur.name) : acc, [])
注意:简化版本会自动过滤name值为
''、0、null、false的项,如果需要保留这类假值,请使用属性存在性判断的写法。
内容的提问来源于stack exchange,提问作者Fernando Vasquez
相关产品推荐
相关产品推荐

