假设我有一个对象:
elmo = {
color: 'red',
annoying: true,
height: 'unknown',
meta: { one: '1', two: '2'}
};
我想用它的属性子集创建一个新对象。
// pseudo code
subset = elmo.slice('color', 'height')
//=> { color: 'red', height: 'unknown' }
我怎样才能做到呢?
假设我有一个对象:
elmo = {
color: 'red',
annoying: true,
height: 'unknown',
meta: { one: '1', two: '2'}
};
我想用它的属性子集创建一个新对象。
// pseudo code
subset = elmo.slice('color', 'height')
//=> { color: 'red', height: 'unknown' }
我怎样才能做到呢?
当前回答
虽然它有点啰嗦,但通过使用Array.prototype.reduce,你可以完成其他人在2年前推荐的underscore/lodash。
var subset = ['color', 'height'].reduce(function(o, k) { o[k] = elmo[k]; return o; }, {});
这种方法从另一方面解决了这个问题:而不是获取一个对象并将属性名传递给它来提取,而是获取一个属性名数组并将它们简化为一个新对象。
While it's more verbose in the simplest case, a callback here is pretty handy, since you can easily meet some common requirements, e.g. change the 'color' property to 'colour' on the new object, flatten arrays, etc. -- any of the things you need to do when receiving an object from one service/library and building a new object needed somewhere else. While underscore/lodash are excellent, well-implemented libs, this is my preferred approach for less vendor-reliance, and a simpler, more consistent approach when my subset-building logic gets more complex.
编辑:es7版本相同:
const subset = ['color', 'height'].reduce((a, e) => (a[e] = elmo[e], a), {});
编辑:这也是咖喱的一个很好的例子!让'pick'函数返回另一个函数。
const pick = (...props) => o => props.reduce((a, e) => ({ ...a, [e]: o[e] }), {});
上面的方法非常接近于另一种方法,除了它让你在运行中构建一个“picker”。如。
pick('color', 'height')(elmo);
这种方法的特别之处在于,你可以很容易地将所选的“picks”传递到任何带有函数的对象中,例如Array#map:
[elmo, grover, bigBird].map(pick('color', 'height'));
// [
// { color: 'red', height: 'short' },
// { color: 'blue', height: 'medium' },
// { color: 'yellow', height: 'tall' },
// ]
其他回答
扩展内置原型有其优势。如果你使用Object.defineProperty,你不会产生任何污染-唯一剩下的问题是与未来属性的冲突(例如,你定义Object.prototype。在将来,ES标准将Object.prototype.slice定义为具有不同的功能-现在您的代码正在破坏Object.prototype.slice中应该存在的预期功能)。
...... ....... ...... .....Elmo的身高不是未知的(!!)
Object.defineProperty(Object.prototype, 'slice', { 可列举的:假的, 可写:没错, 值:function(…args) { 让o = {}; for (let k of args) this. hasownproperty (k) && (o[k] = this[k]); 返回啊; } }); Elmo = { 颜色:红色, 讨厌:没错, 高度:“24”, Meta: {1: '1', 2: '2'} }; console.log(艾尔摩。片(“颜色”、“高度”)); console.log('看,没有污染:); 对于(let k in elmo) console.log(' - ${k} ');
Try
const elmo={color:"red",annoying:!0,height:"unknown",meta:{one:"1",two:"2"}};
const {color, height} = elmo; newObject = ({color, height});
console.log(newObject); //{ color: 'red', height: 'unknown' }
只是另一种方式……
var elmo = {
color: 'red',
annoying: true,
height: 'unknown',
meta: { one: '1', two: '2'}
}
var subset = [elmo].map(x => ({
color: x.color,
height: x.height
}))[0]
你可以在Objects =)数组中使用这个函数
使用“with”语句的简写对象文字语法
还没有人演示过这种方法,可能是因为它很糟糕,你不应该这么做,但我觉得必须把它列出来。
Var o = {a:1,b:2,c:3,d:4,e:4,f:5} (o) { Var输出= {a,b,f} } console.log(输出)
利:你不需要输入两次属性名。
缺点:由于许多原因,不建议使用“with”语句。
结论:它很有效,但不要使用它。
我建议看看Lodash;它有很多实用函数。
例如,pick()就是你要找的东西:
var subset = _.pick(elmo, ['color', 'height']);
小提琴