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

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),
 };

当前回答

在EcmaScript2015中,你可以使用Object.assign:

Object.assign(a, conditionB ? { b: 1 } : null,
                 conditionC ? { c: 2 } : null,
                 conditionD ? { d: 3 } : null);

var a,条件b,条件c,条件; 条件c = true; A = {}; 对象。赋值(a, conditionB ?{b: 1}: null, conditionC吗?{c: 2}: null, conditionD吗?{d: 3}: null); console.log(一个);

一些评论:

对象。Assign会原地修改第一个参数,但它也会返回更新后的对象:所以你可以在一个更大的表达式中使用这个方法来进一步操作对象。 而不是null,你可以传递undefined或{},有相同的结果。您甚至可以提供0,因为原始值被包装了,而Number没有自己的可枚举属性。

更简洁

进一步考虑第二点,你可以把它缩短如下(正如@Jamie指出的那样),因为假值没有自己的可枚举属性(false, 0, NaN, null, undefined,”,除了document.all):

Object.assign(a, conditionB && { b: 1 },
                 conditionC && { c: 2 },
                 conditionD && { d: 3 });

条件a,条件b,条件c,条件d; conditionC = "this is true "; 条件= NaN;/ / falsy a = {}; 物体。assign(a,条件b && {b: 1}, 条件&& {c: 2}, 条件&& {d: 3}); console.log (a);

其他回答

我用另一个选项做了一个小的基准测试。我喜欢从一些物体上去除“累赘”。通常是错误的值。

以下是本尼的结果:

清洁

const clean = o => {
    for (const prop in o) if (!o) delete o[prop];
}

clean({ value });

传播

let a = {
    ...(value && {b: value})
};

if

let a = {};
if (value) {
    a.b = value;
}

结果

clean  :  84 918 483 ops/s, ±1.16%    | 51.58% slower    
spread :  20 188 291 ops/s, ±0.92%    | slowest, 88.49% slower    
if     : 175 368 197 ops/s, ±0.50%    | fastest
const isAdult = true;

const obj = {
  ...(isAdult ? { age: 18 }: { age: 17}),
};

//>> { student: 18 }
var a = {
    ...(condition ? {b: 1} : '') // if condition is true 'b' will be added.
}

我希望这是基于条件添加条目的更有效的方法。 有关如何有条件地在对象字面量中添加条目的详细信息。

性能测试

经典的方法

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

VS

展开算子法

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

结果:

经典的方法要快得多,所以要考虑到语法糖化更慢。

testClassicConditionFulfilled ();// ~ 234.9ms testClassicConditionNotFulfilled ();/ / ~ 493 1ms。 testSpreadOperatorConditionFulfilled ();/ / ~紧密4ms。 testSpreadOperatorConditionNotFulfilled ();/ / ~ 2239。卫生组织

function testSpreadOperatorConditionFulfilled() { const value = 5; console.time('testSpreadOperatorConditionFulfilled'); for (let i = 0; i < 200000000; i++) { let a = { ...(value && {b: value}) }; } console.timeEnd('testSpreadOperatorConditionFulfilled'); } function testSpreadOperatorConditionNotFulfilled() { const value = undefined; console.time('testSpreadOperatorConditionNotFulfilled'); for (let i = 0; i < 200000000; i++) { let a = { ...(value && {b: value}) }; } console.timeEnd('testSpreadOperatorConditionNotFulfilled'); } function testClassicConditionFulfilled() { const value = 5; console.time('testClassicConditionFulfilled'); for (let i = 0; i < 200000000; i++) { let a = {}; if (value) a.b = value; } console.timeEnd('testClassicConditionFulfilled'); } function testClassicConditionNotFulfilled() { const value = undefined; console.time('testClassicConditionNotFulfilled'); for (let i = 0; i < 200000000; i++) { let a = {}; if (value) a.b = value; } console.timeEnd('testClassicConditionNotFulfilled'); } testClassicConditionFulfilled(); // ~ 234.9ms testClassicConditionNotFulfilled(); // ~493.1ms testSpreadOperatorConditionFulfilled(); // ~2649.4ms testSpreadOperatorConditionNotFulfilled(); // ~2278.0ms

const obj = {
   ...(condition) && {someprop: propvalue},
   ...otherprops
}

现场演示:

Const obj = { (true) && {someprop: 42}, …(false) && {nonprop: "foo"}, …({})&&{狡猾的:"hello"}, } console.log (obj);