Me gustaría crear un objeto con un miembro agregado condicionalmente. El enfoque simple es:
var a = {};
if (someCondition)
a.b = 5;
Ahora, me gustaría escribir un código más idiomático. Estoy intentando:
a = {
b: (someCondition? 5 : undefined)
};
Pero ahora, bes un miembro de acuyo valor es undefined. Este no es el resultado deseado.
¿Hay alguna solución útil?
Actualizar
Busco una solución que pueda manejar el caso general con varios miembros.
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),
};
javascript
viebel
fuente
fuente

a.b, la recuperacióna.bvolvería deundefinedtodos modos.inse utiliza el operador.Respuestas:
En Javascript puro, no puedo pensar en nada más idiomático que su primer fragmento de código.
Sin embargo, si el uso de la biblioteca jQuery no está descartado, entonces $ .extend () debería cumplir con sus requisitos porque, como dice la documentación:
Por lo tanto, puedes escribir:
Y obtenga los resultados que espera (si
conditionBes asífalse, entoncesbno existiráa).fuente
Creo que @InspiredJW lo hizo con ES5, y como señaló @trincot, usar es6 es un mejor enfoque. Pero podemos agregar un poco más de azúcar, utilizando el operador de propagación y la evaluación lógica Y de cortocircuito:
fuente
Null/Undefined Are Ignored, no dice quefalsese ignore. Los transpiladores pueden permitir esto en este momento, pero ¿es compatible? Lo siguiente debería ser{...someCondition ? {b: 5} : null}pero no es tan compacto.Object.assigny tiene menor prioridad que el operador &&. Ignora el valor sin propiedad (booleano, nulo, indefinido, número) y agrega todas las propiedades del objeto después del...lugar. recuerde que el&&operador devuelve el valor correcto si es verdadero o falso de lo contrario. por lo que sisomeConditiones cierto,{b : 5}será pasado al...operador, lo que resulta en la adición de la propiedadbqueacon valor5. essomeConditionfalso, sefalsepasará al...operador. resultando en nada agregado. Es inteligente. Me encanta.Con EcmaScript2015 puede usar
Object.assign:Mostrar fragmento de código
Algunas observaciones:
Object.assignmodifica el primer argumento en el lugar, pero también devuelve el objeto actualizado: para que pueda usar este método en una expresión más grande que manipule aún más el objeto.nullusted podría pasarundefinedo{}, con el mismo resultado. Incluso podría proporcionar en su0lugar, porque los valores primitivos están envueltos, yNumberno tienen propiedades propias enumerables .Aún más conciso
Teniendo además el segundo punto, se podría acortar la siguiente manera (como @Jamie tiene cabo puntas), como valores Falsy no tienen propiedades enumerables propias (
false,0,NaN,null,undefined,'', exceptodocument.all):Mostrar fragmento de código
fuente
Demo en vivo:
fuente
El uso de sintaxis extendida con booleano (como se sugiere aquí) no es una sintaxis válida. Spread solo se puede usar con iterables .
Sugiero lo siguiente:
fuente
{...false}{...false}es una sintaxis válidaCopyDataPropertiesse realiza en el valor (falseen este caso). Esto implica boxear una primitiva (secciones 7.3.23, 7.1.13). El enlace que tiene a MDN menciona esta "excepción" entre paréntesis.¿Qué pasa con el uso de propiedades de objetos mejorados y solo establece la propiedad si es verdadera, por ejemplo:
Entonces, si no se cumple la condición, no crea la propiedad preferida y, por lo tanto, puede descartarla. Ver: http://es6-features.org/#ComputedPropertyNames
ACTUALIZACIÓN: es aún mejor seguir el enfoque de Axel Rauschmayer en su artículo de blog sobre agregar condicionalmente entradas dentro de literales y matrices de objetos ( http://2ality.com/2017/04/conditional-literal-entries.html ):
Me ayudó mucho.
fuente
falseclave adicional . Por ejemplo,{[true && 'a']: 17, [false && 'b']: 42}es{a:17, false: 42}...isConditionTrue() && { propertyName: 'propertyValue' }más simplificado
fuente
Si el objetivo es que el objeto parezca autónomo y esté dentro de un conjunto de llaves, puede intentar esto:
fuente
Si desea hacer este lado del servidor (sin jquery), puede usar lodash 4.3.0:
Y esto funciona usando lodash 3.10.1
fuente
Espero que esta sea la forma más eficiente de agregar una entrada en función de la condición. Para obtener más información sobre cómo agregar entradas condicionalmente dentro de un objeto literal.
fuente
[...condition?'':['item']]esto agregará un elemento de cadena en la matrizEsto ha sido respondido durante mucho tiempo, pero mirando otras ideas se me ocurrió una derivada interesante:
Asigne valores indefinidos a la misma propiedad y elimínelos después
Cree su objeto utilizando un constructor anónimo y siempre asigne miembros indefinidos al mismo miembro ficticio que elimine al final. Esto le dará una sola línea (no demasiado compleja, espero) por miembro + 1 línea adicional al final.
fuente
Puede agregar todos sus valores indefinidos sin condiciones y luego usar
JSON.stringifypara eliminarlos todos:fuente
Yo haría esto
Editado con una versión de código de línea
fuente
a = undefined. Se puede cambiar fácilmente conreturn { b: undefined };: /return {};enelsepartea = condition ? {b:5} : undefined;Usando la biblioteca lodash, puedes usar _.omitBy
Esto resulta útil cuando tiene solicitudes que son opcionales
fuente
Creo que su primer enfoque para agregar miembros condicionalmente está perfectamente bien. Realmente no estoy de acuerdo con no querer tener un miembro
bdeaun valor deundefined. Es bastante simple agregar unundefinedcheque con el uso de unforbucle con elinoperador. Pero de todos modos, podría escribir fácilmente una función para filtrarundefinedmiembros.También puede usar el
deleteoperador para editar el objeto en su lugar.fuente
Envolver en un objeto
Algo como esto es un poco más limpio
Envolver en una matriz
O si desea utilizar el método de Jamie Hill y tener una lista muy larga de condiciones, debe escribir la
...sintaxis varias veces. Para hacerlo un poco más limpio, puede envolverlos en una matriz y luego usarlosreduce()para devolverlos como un solo objeto.O usando la
map()funciónfuente
Esta es la solución más sucinta que se me ocurre:
fuente
Defina una var por
lety simplemente asigne una nueva propiedadAhora el
msgconvertidoEn mi opinión, esta es una solución muy simple y fácil.
fuente
Usando la biblioteca lodash, puedes usar _.merge
falsey la condición C estrue, entoncesa = { c: 5 }true, entoncesa = { b: 4, c: 5 }false, entoncesa = {}fuente
lodash@^4.0.0.undefinedestán siendo incluidos en mi caso.