如何实现从对象与属性列表中创建选取属性组成的对象?
嘿,你的这段代码思路方向是对的,但语法和逻辑上有点问题哦——你现在写的是把整个obj赋值给fields数组的解构,这完全没法实现提取指定属性的需求。让我给你几个靠谱的实现方式:
方法1:使用
Array.reduce()(最常用的实现方式) 这个方法逻辑直观,遍历传入的属性列表,把原对象中存在的属性逐一添加到新对象里:
const pick = (obj, ...fields) => { return fields.reduce((newObj, field) => { // 先检查原对象是否拥有该属性,避免混入继承来的原型属性 if (obj.hasOwnProperty(field)) { newObj[field] = obj[field]; } return newObj; }, {}); // 初始值设为空对象,作为新对象的起点 };
举个调用例子:pick({name: 'Alice', age: 30, city: 'NY'}, 'name', 'age'),会返回{name: 'Alice', age: 30}。
方法2:使用
Object.fromEntries()(更简洁的ES6+写法) 如果你的运行环境支持ES2019及以上,可以用这个更短的写法:
const pick = (obj, ...fields) => { return Object.fromEntries( fields.filter(field => obj.hasOwnProperty(field)) .map(field => [field, obj[field]]) ); };
原理是先过滤出原对象存在的属性,把它们转成[key, value]的数组格式,再用Object.fromEntries()把这个数组转成目标对象。
方法3:使用
forEach遍历(新手友好版) 如果你觉得reduce的逻辑有点绕,用forEach循环赋值会更直白:
const pick = (obj, ...fields) => { const newObj = {}; fields.forEach(field => { if (obj.hasOwnProperty(field)) { newObj[field] = obj[field]; } }); return newObj; };
额外注意点:
- 代码里的
obj.hasOwnProperty(field)是可选的,但加上它可以避免误选对象继承自原型链的属性(比如Object.prototype.toString这类);如果你明确需要包含继承属性,可以去掉这个判断。 - 你原代码里的
...fields参数是完全正确的,这样可以接收任意数量的属性名参数,灵活度很高。
内容的提问来源于stack exchange,提问作者MeltedStack
相关产品推荐
相关产品推荐

