Javascript 在Javascript中,如何有条件地向对象添加成员?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11704267/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 06:47:43  来源:igfitidea点击:

In Javascript, how to conditionally add a member to an object?

javascript

提问by viebel

I would like to create an object with a member added conditionally. The simple approach is:

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

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

Now, I would like to write a more idiomatic code. I am trying:

现在,我想写一个更地道的代码。我在尝试:

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

But now, bis a member of awhose value is undefined. This is not the desired result.

但现在,ba其值为的成员undefined。这不是想要的结果。

Is there a handy solution?

有方便的解决方案吗?

Update

更新

I seek for a solution that could handle the general case with several members.

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

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

采纳答案by Frédéric Hamidi

In pure Javascript, I cannot think of anything more idiomatic than your first code snippet.

在纯 Javascript 中,我想不出比你的第一个代码片段更惯用的东西了。

If, however, using the jQuery library is not out of the question, then $.extend()should meet your requirements because, as the documentation says:

但是,如果使用 jQuery 库不是不可能,那么$.extend()应该可以满足您的要求,因为正如文档所说:

Undefined properties are not copied.

不复制未定义的属性。

Therefore, you can write:

因此,您可以编写:

var a = $.extend({}, {
    b: conditionB ? 5 : undefined,
    c: conditionC ? 5 : undefined,
    // and so on...
});

And obtain the results you expect (if conditionBis false, then bwill not exist in a).

并获得您期望的结果(如果conditionBfalseb则将不存在于a)。

回答by Jamie Hill

I think @InspiredJW did it with ES5, and as @trincot pointed out, using es6 is a better approach. But we can add a bit more sugar, by using the spread operator, and logical AND short circuit evaluation:

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

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

回答by trincot

With EcmaScript2015 you can use Object.assign:

使用 EcmaScript2015,您可以使用Object.assign

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

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

console.log(a);

Some remarks:

一些备注:

Even more concise

更简洁

Taking the second point further, you could shorten it as follows (as @Jamie has pointed out), as falsy values have no own enumerable properties (false, 0, NaN, null, undefined, '', except document.all):

进一步考虑第二点,您可以将其缩短如下(正如@Jamie 指出的那样),因为虚假值没有自己的可枚举属性(false, 0, NaN, null, undefined, '', except document.all):

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

var a, conditionB, conditionC, conditionD;
conditionC = "this is truthy";
conditionD = NaN; // falsy
a = {};
Object.assign(a, conditionB && { b: 1 },
                 conditionC && { c: 2 },
                 conditionD && { d: 3 });
console.log(a);

回答by Lagistos

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

Live Demo:

现场演示:

const obj = {
  ...(true) && {someprop: 42},
  ...(false) && {nonprop: "foo"},
  ...({}) && {tricky: "hello"},
}

console.log(obj);

回答by Itai Noam

Using spread syntax with boolean (as suggested here) is not valid syntax. Spread can only be use with iterables.

使用带有布尔值的扩展语法(如此处所建议的)不是有效的语法。Spread 只能与 iterables一起使用。

I suggest the following:

我建议如下:

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

回答by Dimitri Reifschneider

What about using Enhanced Object Properties and only set the property if it is truthy, e.g.:

使用增强的对象属性怎么样,并且只在它为真时才设置属性,例如:

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

So if the condition is not met it doesn't create the preferred property and thus you can discard it. See: http://es6-features.org/#ComputedPropertyNames

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

UPDATE:It is even better to follow the approach of Axel Rauschmayer in his blog article about conditionally adding entries inside object literals and arrays (http://2ality.com/2017/04/conditional-literal-entries.html):

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

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

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

Quite helped me a lot.

对我帮助很大。

回答by Faheel Khan

more simplified,

更简化,

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

回答by Madhankumar

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

I hope this is the much efficient way to add an entry based on the condition. For more info on how to conditionally add entries inside an object literals.

我希望这是基于条件添加条目的非常有效的方法。有关如何有条件地在对象文字中添加条目的更多信息。

回答by Mickl

If you wish to do this server side (without jquery), you can use lodash 4.3.0:

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

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


And this works using lodash 3.10.1

这适用于 lodash 3.10.1

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

回答by Casey Chu

If the goal is to have the object appear self-contained and be within one set of braces, you could try this:

如果目标是让对象看起来是自包含的并且在一组大括号内,你可以试试这个:

var a = new function () {
    if (conditionB)
        this.b = 5;

    if (conditionC)
        this.c = 5;

    if (conditionD)
        this.d = 5;
};