在Javascript中,如何有条件地向对象添加成员?
我想创建一个有条件添加成员的对象。 简单的方法是:在Javascript中,如何有条件地向对象添加成员?,javascript,Javascript,我想创建一个有条件添加成员的对象。 简单的方法是: var a = {}; if (someCondition) a.b = 5; 现在,我想写一段更地道的代码。我正在努力: a = { b: (someCondition? 5 : undefined) }; 但是现在,b是a的成员,其值为未定义。这不是期望的结果 有简便的解决办法吗 更新 var a = _.merge({}, { b: conditionB ? 4 : undefined, c: cond
var a = {};
if (someCondition)
a.b = 5;
现在,我想写一段更地道的代码。我正在努力:
a = {
b: (someCondition? 5 : undefined)
};
但是现在,b
是a
的成员,其值为未定义。这不是期望的结果
有简便的解决办法吗
更新
var a = _.merge({}, {
b: conditionB ? 4 : undefined,
c: conditionC ? 5 : undefined,
})
我寻求一种解决办法,可以与几个成员一起处理一般情况
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),
};
我会这么做
var a=someCondition?{b:5}:{};
在纯Javascript中,我想不出比您的第一个代码片段更地道的了
但是,如果使用jQuery库不是不可能的,那么应该满足您的要求,因为正如文档所述:
未定义的属性不会被复制
因此,你可以写:
var a = $.extend({}, {
b: conditionB ? 5 : undefined,
c: conditionC ? 5 : undefined,
// and so on...
});
并获得您期望的结果(如果conditionB
为false
,则b
将不存在于a
)。我认为您第一种有条件地添加成员的方法是非常好的。我真的不同意不希望有一个a
的b
成员的值为未定义
。使用for
循环和in
操作符添加未定义的检查非常简单。但无论如何,您可以轻松编写一个函数来过滤未定义的成员
var filterUndefined = function(obj) {
var ret = {};
for (var key in obj) {
var value = obj[key];
if (obj.hasOwnProperty(key) && value !== undefined) {
ret[key] = value;
}
}
return ret;
};
var a = filterUndefined({
b: (conditionB? 5 : undefined),
c: (conditionC? 5 : undefined),
d: (conditionD? 5 : undefined),
e: (conditionE? 5 : undefined),
f: (conditionF? 5 : undefined),
g: (conditionG? 5 : undefined),
});
您还可以使用delete
操作符在位编辑对象。如果目标是使对象显示为独立的,并且位于一组大括号内,您可以尝试以下操作:
var a = new function () {
if (conditionB)
this.b = 5;
if (conditionC)
this.c = 5;
if (conditionD)
this.d = 5;
};
这一点早就得到了回答,但看看其他想法,我想出了一些有趣的衍生工具:
将未定义的值指定给同一属性,然后将其删除
使用匿名构造函数创建对象,并始终将未定义的成员分配给在最后删除的同一虚拟成员。这将给你一个单一的行(不太复杂,我希望)每个成员+1额外的行在最后
var a = new function() {
this.AlwaysPresent = 1;
this[conditionA ? "a" : "undef"] = valueA;
this[conditionB ? "b" : "undef"] = valueB;
this[conditionC ? "c" : "undef"] = valueC;
this[conditionD ? "d" : "undef"] = valueD;
...
delete this.undef;
};
如果希望在服务器端执行此操作(无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));
使用ECMAScript 2015,您可以使用:
var a、conditionB、conditionC、conditionD;
条件c=真;
a={};
赋值(a,条件b?{b:1}:null,
条件c?{c:2}:null,
条件d?{d:3}:null);
控制台日志(a)代码>我认为@InspiredJW使用ES5做到了这一点,正如@trincot指出的,使用es6是一种更好的方法。但我们可以通过使用spread运算符以及逻辑和短路评估来添加更多的糖:
const a = {
...(someCondition && {b: 5})
}
使用增强的对象属性并仅在属性为truthy时设置该属性如何,例如:
[isConditionTrue() && 'propertyName']: 'propertyValue'
因此,如果不满足条件,它不会创建首选属性,因此您可以放弃它。
见:
更新:
更好的做法是遵循Axel Rauschmayer在其博客文章中关于在对象文本和数组()中有条件地添加条目的方法:
这对我帮助很大
var a = {
...(condition ? {b: 1} : '') // if condition is true 'b' will be added.
}
我希望这是根据条件添加条目的更有效的方法。
有关如何在对象文本中有条件地添加条目的详细信息。使用lodash库,您可以使用\uuu.merge
var a = _.merge({}, {
b: conditionB ? 4 : undefined,
c: conditionC ? 5 : undefined,
})
如果条件B为false
,条件c为true
,则a={c:5}
如果条件b和条件c都是true
,则a={b:4,c:5}
如果条件B和条件C都是false
,则a={}
使用lodash库,您可以使用
var a = _.omitBy({
b: conditionB ? 4 : undefined,
c: conditionC ? 5 : undefined,
}, _.IsUndefined)
当您有可选的请求时,这将非常方便
var a = _.omitBy({
b: req.body.optionalA, //if undefined, will be removed
c: req.body.optionalB,
}, _.IsUndefined)
现场演示:
const obj={
…(对)&{someprop:42},
…(假)&{nonprop:“foo”},
…({})和{棘手的:“你好”},
}
控制台日志(obj)
您可以无条件添加所有未定义的值,然后使用JSON.stringify
将它们全部删除:
const person = {
name: undefined,
age: 22,
height: null
}
const cleaned = JSON.parse(JSON.stringify(person));
// Contents of cleaned:
// cleaned = {
// age: 22,
// height: null
// }
我建议如下:
const a={
…(某些条件?{b:5}:{})
}
包装成一个对象
像这样的东西比较干净
const obj = {
X: 'dataX',
Y: 'dataY',
//...
}
const list = {
A: true && 'dataA',
B: false && 'dataB',
C: 'A' != 'B' && 'dataC',
D: 2000 < 100 && 'dataD',
// E: conditionE && 'dataE',
// F: conditionF && 'dataF',
//...
}
Object.keys(list).map(prop => list[prop] ? obj[prop] = list[prop] : null)
或者使用map()
函数
const obj = {
X: 'dataX',
Y: 'dataY',
//...
}
const array = [
true && { A: 'dataA'},
false && { B: 'dataB'},
'A' != 'B' && { C: 'dataC'},
2000 < 100 && { D: 'dataD'},
// conditionE && { E: 'dataE'},
// conditionF && { F: 'dataF'},
//...
].map(val => Object.assign(obj, val))
const obj={
X:'dataX',
Y:‘数据Y’,
//...
}
常量数组=[
true&&{A:'dataA'},
false&&{B:'dataB'},
'A'!='B'&&{C:'dataC'},
2000<100&{D:'dataD'},
//条件&&{E:'dataE'},
//条件F&&{F:'dataF'},
//...
].map(val=>Object.assign(obj,val))
这是我能想到的最简洁的解决方案:
var a = {};
conditionB && a.b = 5;
conditionC && a.c = 5;
conditionD && a.d = 5;
// ...
更简单一点
const a = {
...(condition && {b: 1}) // if condition is true 'b' will be added.
}
通过let
定义一个var,然后只分配新属性
let msg={
至:hito@email.com",
来自:hifrom@email.com",
主题:“联系方式”,
};
如果(文件上传形式){//,条件如下
msg.attachments=[//此处“attachments”是添加到msg Javascript对象的新属性
{
内容:“附件”,
文件名:“文件名”,
类型:“mime_类型”,
处置:“附件”,
},
];
}
现在msg
变成
{
to: "hito@email.com",
from: "hifrom@email.com",
subject: "Contact form",
attachments: [
{
content: "attachment",
filename: "filename",
type: "mime_type",
disposition: "attachment",
},
]
}
在我看来,这是一个非常简单的解决方案。更好的答案:
const a = {
...(someCondition ? {b: 5} : {})
}
性能测试
经典方法
const a = {};
if (someCondition)
a.b = 5;
const a2 = {
...(someCondition && {b: 5})
}
VS
扩展运算符进近
const a = {};
if (someCondition)
a.b = 5;
const a2 = {
...(someCondition && {b: 5})
}
结果:
经典的方法要快得多,所以要考虑到语法加糖的速度较慢
TestClassicConditionCompleted();//~234.9ms
TestClassicConditionNotCompleted();//~493.1ms
TestSpreadOperator条件已满足();//~2649.4ms
TestSpreadOperator条件未满足();//~2278.0ms
函数测试扩展运算符条件已满足(){
常数值=5;
console.time('testSp
const a2 = {
...(someCondition && {b: 5})
}
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 trueCondition = true;
const falseCondition = false;
const obj = {
...(trueCondition && { student: 10 }),
...(falseCondition && { teacher: 2 }),
};
// { student: 10 }