Digamos que tengo este caso de uso literal de cadena:
function getClassNames(props){ my_classNames = `class-nameA class-nameB ${props?.one} ${props?.two} class-nameC`; return my_classNames; } console.log(getClassNames({one: 'class-name-one', two: 'class-name-two'})) // prints: class-nameA class-nameB class-name-one class-name-two class-nameC console.log(getClassNames({two: 'class-name-two'})) // prints: class-nameA class-nameB undefined class-name-two class-nameC console.log(getClassNames()) // prints: class-nameA class-nameB undefined undefined class-nameCEl problema es que cuando alguna de las claves de los accesorios no está definida, se imprime sin definir. Quiero que imprima una cadena vacía en su lugar.
Una solución a esto es usar una evaluación OR de cortocircuito como esta:
function getClassNames(props){ my_classNames = `class-nameA class-nameB ${props?.one || ''} ${props?.two || ''} class-nameC`; return my_classNames; } console.log(getClassNames()) // prints: class-nameA class-nameB class-nameCO una solución mejor (para evitar espacios adicionales), usar la solución anterior con cortocircuito Y evaluación como esta:
function getClassNames(props){ my_classNames = `class-nameA class-nameB${props?.one && ' '+props?.one || ''}${props?.two && ' '+props?.two || ''}class-nameC`; return my_classNames; } console.log(getClassNames()) // prints: class-nameA class-nameB class-nameCPara hacerlo más conciso, puedo envolver duplicados/repeticiones en una solución anterior a una función:
function getClassNames(props){ my_classNames = `class-nameA class-nameB${concatWithSpace(props?.one)}${concatWithSpace(props?.two)}class-nameC`; return my_classNames; } function concatWithSpace(str){ return str && ' '+str || ''; } console.log(getClassNames()) // prints: class-nameA class-nameB class-nameC ¿Existe una forma integrada más concisa (sintaxis) para imprimir una cadena vacía (en lugar de undefined ) para variables encadenadas opcionalmente sin usar las soluciones "no tan concisas" anteriores que mencioné?
No use una cadena de plantilla, sino una matriz y realice algún procesamiento en ella:
function getClassNames(props){ const my_classNames = ['class-nameA', 'class-nameB', props?.one, props?.two, 'class-nameC']; return my_classNames.filter(Boolean).join(' '); }Esto también funciona correctamente con partes opcionales al principio o al final, o una matriz vacía.
¿Quizás desestructurando props y asignando valores predeterminados?
como esto:
function getClassNames({ one = '', two = '' }){ my_classNames = `class-nameA class-nameB ${one} ${two} class-nameC`; return my_classNames; }(EDITAR)
o puede escribir una función de ayuda para los literales de plantilla ( plantilla etiquetada )
/* types textContent(stringList: TemplateStringsArray, ...valueList: unknown[]) */ function classString(stringList, ...valueList) { return stringList.reduce((text, string, i) => ( text + string + (valueList[i] || '') ), '').replace(/ +/g, ' '); // (optional) replace multiple spaces with single } var one = undefined; var two = undefined; var three = "something"; console.log(classString`class-nameA class-nameB ${one} ${two} ${three} class-nameC`);