10

Tengo una duda sobre esta función:

function qwerty(n) {
  return function(y) {
      return y + 1
    }
    (++n) + n
}

console.log(qwerty(2));

El resultado arrojado es 7. ¿Por qué? No lo acabo de entender, se supone que con este sentencia return function(y)..... devolvería la función ¿No? O sea, todo lo que hay después de return, no debería ser procesado.

Alvaro Montoro
  • 48,157
  • 26
  • 100
  • 179
H. Díaz
  • 556
  • 2
  • 16

3 Answers3

13

Esto se debe a que con el return no estás devolviendo una función si no el resultado de la llamada a esa función. La manera en la que se están poniendo los espacios es algo raro (seguramente a propósito) y lleva a confusión, que es por lo que el resultado no es el que parecería obvio.

Vamos a descomponer el código poco a poco. Originalmente el código es éste:

function qwerty(n) {
  return function(y) {
      return y + 1
    }
    (++n) + n
}

console.log(qwerty(2));

Pero eso es realmente equivalente a esto quitando el salto de línea:

function qwerty(n) {
  return function(y) {
      return y + 1;
    }(++n) + n;
}

console.log(qwerty(2));

Eso ya da una idea de por dónde va la cosa. Vamos a mover la definición de la función fuera y a darle un nombre para que no sea tan confusa. Y entonces el código es similar a esto:

function suma1(y) {
  return y + 1;
}

function qwerty(n) {
  return suma1(++n) + n;
}

console.log(qwerty(2));

Al hacer (++n) se está sumando 1 a n antes de llamar a la función, por lo que es como hacer suma1(3) que va a devolver 4, y n ya vale 3 por lo que el resultado es 7 (3+4). Para que sea más claro, esto es equivalente al código inicial:

function suma1(y) {
  return y + 1;
}

function qwerty(n) {
  n = n + 1;
  return suma1(n) + n;
}

console.log(qwerty(2));
Alvaro Montoro
  • 48,157
  • 26
  • 100
  • 179
  • 2
    Muchas gracias por la explicación y atención prestada. No había caído en que el paréntesis realizaba la llamada a la función anónima. Gracias. – H. Díaz Aug 03 '19 at 20:09
9

Esto se conoce como clausuras , y estas declarando una funcion y ejecutandola (función anónima) devolviendo el valor de la ejecucion de la funcion anonima mas el valor de n

Primero hagamos un ejemplo de función anónima y que se ejecute!:

var persona = " H. Díaz"
console.log(
function (nombre) {
  return "Hey " + nombre

}(persona)
)

Una vez explicado esto; Prestemos atención a tu código las siguientes lineas:

  function(y) {
      return y + 1
    }
    (++n) + n

Estas creando una función anónima y ejecutándola al final con los parentesis () pasando por parámetros ++n , esta forma como esta primero se asigna y una vez asignado se ejecuta la función anónima y sumarle el valor de n (que previamente hicistes ++n)

Ejecutemos el mismo código en el snippet cambiando n = 2

console.log(
  function(y) {
    return y + 1
  }(2 + 2) + 2
)

pero que tal si cambiamos el codigo para que se vea un poco mejor , el codigo que tienes es equivalente a :

function qwerty(n) {
  function incremento(y){
    return y + 1
  }
  n = n + 1;
  return (incremento(n) + n)
}

console.log(qwerty(2));
Incluso se puede hacer de la siguiente forma:

function qwerty(n) {
   n = n + 1;
  return function (){
    return n + n + 1
  }()
 
}

console.log(qwerty(2));
Te recomiendo leer esta pregunta es relacionada:

¿Qué sentido tiene un "()" al final de la definición de una función en JavaScript?

El amigo que te dio ese código para empezar JavaScript... no es tu amigo

JackNavaRow
  • 6,836
  • 5
  • 22
  • 49
7

Para comprender cómo funciona, debemos dividir el bloque de la siguiente forma, de adentro hacia afuera:

function(y) {
  return y + 1
}

Es la declaración de una función anónima, que se debe ejecutar inmediatamente después de ser declarada. La forma de ejecutar una función anónima, es pasar los parámetros entre paréntesis:

function(y) {
    return y + 1
}(1)

Por ejemplo, la llamada anterior devolverá 2.

Luego, estamos usando como parámetro el valor ++n, que es un incremento a la variable n antes de usarla. Es decir, se lee suma 1 a n, y envíala como parámetro. Con esto, el valor de entrada para la función anónima es 3 cuando el parámetro n es 2.

function(y) {
    return y + 1
}(++n) // n = 2

Por último, estamos sumando el valor de n al resultado de la función anónima, que, ya que sumamos 1 a su valor a través del operador incremental, ahora su valor es 3. Dado que el resultado de la función es 4, 4 + 3 = 7.

function querty(n) { // n = 2
    return function(y) {
        return y + 1 
    }(++n) + n // ++n = 3
    // function(y){...}(3) = 4
    // n = 3
    // 4 + 3 = 7
}
Niche
  • 1,364
  • 4
  • 15
  • 1
    Gracias, nada como una buena explicación para poder entender las cosas. Está todo entendido! Gracias. – H. Díaz Aug 03 '19 at 20:08