expresión vs instrucción
Al finalizar este tema
Podrás distinguir claramente entre expresión e instrucción y resolverás por ti mismo la duda de "¿por qué no puedo usar un if aquí?".
Las dos unidades básicas de la programación
Al escribir código, existe una distinción fundamental:
- expresión: fragmento de código que produce un valor
- instrucción: unidad de código que ejecuta una acción
Conocer esta distinción te permite responder a preguntas como "¿por qué obtengo un error al colocar este código en este lugar?".
expresión — produce un valor
Una expresión es un fragmento de código que, al evaluarse, se convierte en un único valor:
// Todo esto son expresiones
5 // Literal numérico → 5
"hello" // Literal de cadena → "hello"
2 + 3 // Aritmética → 5
x > 10 // Comparación → true o false
isValid ? "OK" : "X" // Ternario → "OK" o "X"
myFunc(42) // Llamada a función → valor devueltoCaracterística clave de la expresión: se puede asignar a una variable.
const result = 2 + 3; // ✅
const msg = isValid ? "OK" : "X"; // ✅
const val = myFunc(42); // ✅= Si puede estar a la derecha, es una expresión.
statement — realiza una acción
Una statement es una unidad de comando que hace que el programa haga algo:
// Todo esto son sentencias
let x = 5; // Declaración de variable
if (x > 3) { console.log("hi"); } // Condicional
for (let i = 0; i < 5; i++) {} // Bucle
function greet() {} // Declaración de función
return x; // RetornoUna sentencia no crea un valor. Por lo tanto, no se puede asignar a una variable:
const result = if (x > 3) { "yes" }; // ❌ SyntaxError!
const loop = for (let i = 0;;) {}; // ❌ SyntaxError!¿Por qué es importante la distinción?
En JavaScript, hay lugares donde solo se pueden colocar "expresiones". Un ejemplo típico son las llaves en JSX:
// React JSX
<p>{isAdmin ? "Administrador" : "Usuario normal"}</p> // ✅ El ternario es una expresión
<p>{if (isAdmin) { "Administrador" }}</p> // ❌ if es una sentenciaDentro de {} en JSX solo pueden ir expresiones. Las instrucciones if son sentencias, por lo que no se pueden incluir. En su lugar, se utiliza el operador ternario (? :).
// Lo mismo ocurre en un template literal
const msg = `Estado: ${count > 0 ? "presente" : "ausente"}`; // ✅
const msg = `Estado: ${if (count > 0) "presente"}`; // ❌Cosas que cruzan los límites
Algunos códigos pueden usarse tanto como expresión como si fueran sentencias:
// Llamada a función: es una expresión, pero puede usarse sola como sentencia
console.log("hello"); // expression statement
// Asignación: es una expresión, pero puede usarse como sentencia
x = 5; // Expresión de asignación (valor = 5)
// Declaración de función frente a expresión de función
function add(a, b) { return a + b; } // Declaración de función (sentencia)
const add = function(a, b) { return a + b; }; // Expresión de función
const add = (a, b) => a + b; // Función flecha (expresión)function Si comienza con una palabra clave, es una statement (declaración); si se asigna a una variable, es una expression (expresión).
Patrones comunes en la práctica
A menudo surge la necesidad de usar una expression en lugar de una statement:
// Ternario en lugar de if/else
const status = score >= 60 ? "Aprobado" : "Suspenso";
// Operador lógico en lugar de if/else
const name = user.name || "Anónimo";
const display = isVisible && <Component />;
// Mapeo de objeto en lugar de switch
const messages = {
success: "Operación correcta",
error: "Se produjo un error",
loading: "Cargando..."
};
const msg = messages[status] || "Estado desconocido";Expresión de función invocada inmediatamente (IIFE)
Patrón que define y ejecuta una función de inmediato. Al envolver la declaración de la función entre paréntesis, se convierte en una expresión:
// Declaración de función: sentencia
function greet() { return "Hola"; }
// Expresión de función invocada inmediatamente (IIFE): expresión
const result = (function() {
return "Hola";
})();
console.log(result); // "Hola"La IIFE se utiliza para aislar el ámbito de las variables. Aunque su frecuencia de uso disminuyó con la aparición del ámbito de bloque en ES6 (let, const), aún puede verse en código de bibliotecas o en patrones de módulos.
Funciones flecha y expresiones
Las funciones flecha devuelven automáticamente una expresión si se escriben sin llaves:
// Llaves + return: el cuerpo es una sentencia
const double = (x) => { return x * 2; };
// Sin llaves: el cuerpo es una expresión (return implícito)
const double2 = (x) => x * 2;
// Para devolver un objeto literal se necesitan paréntesis
const makeUser = (name) => ({ name, role: "user" });Esta diferencia se manifiesta de manera práctica en el encadenamiento de métodos de arreglos:
const prices = [100, 250, 50, 300];
// Cuerpo de expresión → conciso
const discounted = prices
.filter(p => p > 100)
.map(p => p * 0.9);Cómo distinguirlos con una sola pregunta
| Pregunta | expresión | sentencia |
|---|---|---|
¿Puede colocarse en const x = ___? | ✅ | ❌ |
| ¿Produce un valor? | ✅ | ❌ |
| ¿Puede formar parte de otro código sin punto y coma? | ✅ | ❌ |
«¿Este código produce un valor?». Esta pregunta basta para distinguirlos: si produce un valor es una expresión; si solo realiza una acción es una sentencia.
Diferencias en otros lenguajes
La frontera entre expresiones y sentencias varía según el lenguaje:
# Python: if es una sentencia; el ternario es una expresiónstatus = "Aprobado" if score >= 60 else "Suspenso" # Expresión# if score >= 60: print("Aprobado") # Sentencia
# Python: la asignación es una sentencia (salvo el operador walrus desde 3.8)if (n := len(data)) > 10: # := asigna como expresión print(f"{n} elementos")// Rust: if es una expresión (devuelve un valor)
let status = if score >= 60 { "Aprobado" } else { "Suspenso" };Mientras que en JavaScript el if es una sentencia y el ternario es una expresión, en Rust el propio if es una expresión. Al aprender un nuevo lenguaje, identificar primero este límite permite comprender la sintaxis rápidamente.
Plantillas literales y expresiones
En los literales de plantilla que usan comillas invertidas (`), dentro de ${} solo pueden incluirse expresiones:
const name = "Carlos";
const age = 25;
// ✅ expression
const greeting = `Hola, ${name}. Eres ${age >= 20 ? "adulto" : "menor de edad"}.`;
// ❌ No se puede insertar una sentencia
// `${if (age >= 20) { "adulto" }}` — SyntaxErrorexpresión de declaración — ambas cosas
Hay código que es a la vez una expresión y una declaración:
// Una llamada a función es una expresión y también puede ser una sentencia
console.log("hello"); // Se usa sola como sentencia
const x = console.log; // Devuelve un valor (una función) como expresión
// Una asignación también es expresión y sentencia
let a;
a = 5; // Se usa sola como sentencia
const b = (a = 10); // Devuelve como expresión el valor asignado (10)Esta distinción es la misma en JavaScript y en la mayoría de los lenguajes de programación. Este concepto aparece cada vez que nos encontramos con un "lugar donde se requiere un valor", como en React, literales de plantilla o métodos de arreglos.