我想创建一个对象,有条件地添加成员。 简单的方法是:

var a = {};
if (someCondition)
    a.b = 5;

现在,我想写一个更习惯的代码。我在努力:

a = {
    b: (someCondition? 5 : undefined)
};

但是现在,b是a的一个元素,它的值是未定义的。这不是我们想要的结果。

有没有方便的解决办法?

更新

我寻求一个解决方案,可以处理一般情况与几个成员。

a = {
  b: (conditionB? 5 : undefined),
  c: (conditionC? 5 : undefined),
  d: (conditionD? 5 : undefined),
  e: (conditionE? 5 : undefined),
  f: (conditionF? 5 : undefined),
  g: (conditionG? 5 : undefined),
 };

当前回答

我更喜欢,使用代码这个吧,你可以运行这个代码

const three = {
  three: 3
}

// you can active this code, if you use object `three is null`
//const three = {}

const number = {
  one: 1,
  two: 2,
  ...(!!three && three),
  four: 4
}

console.log(number);

其他回答

更简化,

const a = {
    ...(condition && {b: 1}) // if condition is true 'b' will be added.
}

我认为@InspiredJW用ES5做到了,正如@trincot指出的那样,使用es6是更好的方法。但我们可以添加更多的糖,通过使用扩散运算符,和逻辑与短路计算:

const a = {
   ...(someCondition && {b: 5})
}

如果你想做这个服务器端(不使用jquery),你可以使用lodash 4.3.0:

a = _.pickBy({ b: (someCondition? 5 : undefined) }, _.negate(_.isUndefined));

这是使用lodash 3.10.1实现的

a = _.pick({ b: (someCondition? 5 : undefined) }, _.negate(_.isUndefined));

为了完整起见,如果您想添加额外的描述符,可以使用Object.defineProperty()。注意,我特意添加了enumerable: true,否则该属性不会出现在console.log()中。这种方法的优点是,如果你想添加多个新属性,你也可以使用Object.defineProperties()(然而,这样每个属性都依赖于相同的条件…)

const select = document.getElementById("condition"); const output = document.getElementById("output"); let a = {}; let b = {}; select.onchange = (e) => { const condition = e.target.value === "true"; condition ? Object.defineProperty(a, "b", { value: 5, enumerable: true, }) : (a = {}); condition ? Object.defineProperties(b, { c: { value: 5, enumerable: true, }, d: { value: 6, enumerable: true, }, e: { value: 7, enumerable: true, }, }) : (b = {}); outputSingle.innerText = JSON.stringify(a); outputMultiple.innerText = JSON.stringify(b); }; Condition: <select id="condition"> <option value="false">false</option> <option value="true">true</option> </select> <br/> <br/> Single Property: <pre id="outputSingle">{}</pre><br/> Multiple Properties: <pre id="outputMultiple">{}</pre>

使用增强对象属性并只设置为真值的属性,例如:

[isConditionTrue() && 'propertyName']: 'propertyValue'

因此,如果条件不满足,它不会创建首选属性,因此您可以丢弃它。 见:http://es6-features.org/ ComputedPropertyNames

更新: 最好遵循Axel Rauschmayer在他的博客文章中关于在对象字面量和数组中有条件地添加条目的方法(http://2ality.com/2017/04/conditional-literal-entries.html):)

const arr = [
  ...(isConditionTrue() ? [{
    key: 'value'
  }] : [])
];

const obj = {
  ...(isConditionTrue() ? {key: 'value'} : {})
};

对我帮助很大。