# 1.2 Confusiones

Pronto comenzaremos a explicar cómo `this` funciona realmente, pero primero debemos disipar algunos conceptos erróneos sobre cómo realmente NO funciona.

El nombre "this" crea confusión cuando los desarrolladores tratan de pensarlo demasiado literalmente. Hay dos significados a menudo asumidos, pero ambos son incorrectos.

## Itself

La primera tentación común es asumir que `this` se refiere a la función misma. Esa es una inferencia gramatical razonable, por lo menos.

¿Por qué quieres referirte a una función desde dentro de sí mismo? Las razones más comunes serían cosas como la recursión (llamando a una función desde dentro de sí misma) o tener un manejador de eventos que pueda desvincularse cuando se llama por primera vez.

Los desarrolladores nuevos en los mecanismos de JS a menudo piensan que hacer referencia a la función como un objeto (todas las funciones en JavaScript son objetos!) le permite almacenar el estado (valores en las propiedades) entre las llamadas de función. Aunque esto es ciertamente posible y tiene algunos usos limitados, el resto del libro explicará en muchos otros patrones para mejores lugares para almacenar el estado además del objeto de función.

Pero por un momento exploraremos ese patrón, para ilustrar cómo `this` no permite que una función obtenga una referencia a sí misma tal como podríamos haber asumido.

Considere el siguiente código, donde intentamos rastrear cuántas veces se llamó una función (`foo`):

```javascript
function foo(num) {
    console.log( "foo: " + num );

    // keep track of how many times `foo` is called
    this.count++;
}

foo.count = 0;

var i;

for (i=0; i<10; i++) {
    if (i > 5) {
        foo( i );
    }
}
// foo: 6
// foo: 7
// foo: 8
// foo: 9

// how many times was `foo` called?
console.log( foo.count ); // 0 -- WTF?
```

`foo.count` sigue siendo `0`, aunque las cuatro sentencias `console.log` indican claramente que `foo(...)` se llamó en realidad cuatro veces. La frustración se deriva de una interpretación demasiado literal de lo que significa (en `this.count++`).

Cuando el código ejecuta `foo.count = 0`, de hecho agrega una propiedad `count` al objeto de función `foo`. Sin embargo, para la referencia `this.count` dentro de la función, `this` no apunta en absoluto a ese objeto de función, y así, aunque los nombres de propiedad son los mismos, los objetos raíz son diferentes y se produce confusión.

**Nota**: Un desarrollador responsable debe preguntar en este momento: "Si estaba incrementando una propiedad `count` pero no era la que esperaba, ¿cuál fue el `count` que incrementé?" De hecho, si cavara más profundamente, descubriría que había creado accidentalmente una variable global `count` (véase el Capítulo 2 para saber cómo sucedió!), Y actualmente tiene el valor `NaN`. Por supuesto, una vez que identifica este resultado peculiar, entonces tiene un conjunto de preguntas más: "¿Cómo era global, y por qué terminó `NaN` en lugar de algún valor `count` adecuado?" (Véase el capítulo 2).

En lugar de detenerse en este punto y cavar en por qué la referencia `this` no parece estar comportándose como se esperaba, y responder a esas preguntas difíciles pero importantes, muchos desarrolladores simplemente evitan el problema en conjunto, y hackean hacia otra solución, como la creación de otro Objeto para contener la propiedad `count`:

```javascript
function foo(num) {
    console.log( "foo: " + num );

    // keep track of how many times `foo` is called
    data.count++;
}

var data = {
    count: 0
};

var i;

for (i=0; i<10; i++) {
    if (i > 5) {
        foo( i );
    }
}
// foo: 6
// foo: 7
// foo: 8
// foo: 9

// how many times was `foo` called?
console.log( data.count ); // 4
```

Si bien es cierto que este enfoque "resuelve" el problema, desafortunadamente simplemente ignora el problema real -la falta de comprensión de lo que `this` significa y cómo funciona- y vuelve a caer en la zona de confort de un mecanismo más familiar: alcance léxico .

**Nota**: El alcance léxico es un mecanismo perfectamente fino y útil; No estoy menospreciando el uso de la misma, por cualquier medio (ver el título "Scope & Closures" de esta serie de libros). Pero constantemente adivinar cómo usar `this`, y por lo general estar equivocado, no es una buena razón para retroceder de nuevo al ámbito léxico y nunca aprender por qué esto le escapa.

Para hacer referencia a un objeto de función desde dentro de sí mismo, `this` por sí mismo suele ser insuficiente. Generalmente se necesita una referencia al objeto de función a través de un identificador léxico (variable) que apunte hacia él.

Considere estas dos funciones:

```javascript
function foo() {
    foo.count = 4; // `foo` refers to itself
}

setTimeout( function(){
    // anonymous function (no name), cannot
    // refer to itself
}, 10 );
```

En la primera función, llamada "función nombrada", `foo` es una referencia que se puede utilizar para referirse a la función desde dentro de sí misma.

Pero en el segundo ejemplo, la función de devolución de llamada pasada a `setTimeout(..)` no tiene ningún identificador de nombre (llamada "función anónima"), por lo que no hay forma adecuada de referirse al objeto de función en sí misma.

**Nota**: La referencia a la vieja escuela, pero ahora desaprobada y con el ceño fruncido `arguments.callee`. La referencia dentro de una función también apunta al objeto de función de la función en ejecución. Esta referencia es típicamente la única manera de acceder al objeto de una función anónima desde dentro de sí misma. El mejor enfoque, sin embargo, es evitar el uso de funciones anónimas por completo, al menos para aquellos que requieren una auto-referencia, y en su lugar utilizar una función nombrada (expresión). `arguments.callee` está obsoleto y no debe utilizarse.

Por lo tanto, otra solución a nuestro ejemplo de ejecución habría sido usar el identificador `foo` como una referencia de objeto de función en cada lugar, y no usar `this` en absoluto, lo cual funciona:

```javascript
function foo(num) {
    console.log( "foo: " + num );

    // keep track of how many times `foo` is called
    foo.count++;
}

foo.count = 0;

var i;

for (i=0; i<10; i++) {
    if (i > 5) {
        foo( i );
    }
}
// foo: 6
// foo: 7
// foo: 8
// foo: 9

// how many times was `foo` called?
console.log( foo.count ); // 4
```

Sin embargo, ese enfoque de manera similar a los pasos laterales de la comprensión real de `this` y se basa enteramente en el ámbito léxico de la variable `foo`.

Sin embargo, otra forma de abordar el problema es forzar `this` a apuntar realmente al objeto de función `foo`:

```javascript
function foo(num) {
    console.log( "foo: " + num );

    // keep track of how many times `foo` is called
    // Note: `this` IS actually `foo` now, based on
    // how `foo` is called (see below)
    this.count++;
}

foo.count = 0;

var i;

for (i=0; i<10; i++) {
    if (i > 5) {
        // using `call(..)`, we ensure the `this`
        // points at the function object (`foo`) itself
        foo.call( foo, i );
    }
}
// foo: 6
// foo: 7
// foo: 8
// foo: 9

// how many times was `foo` called?
console.log( foo.count ); // 4
```

**En lugar de evitar** `this`**, lo abrazamos**. Vamos a explicar en un momento cómo funcionan estas técnicas de trabajo mucho más completamente, por lo que no te preocupes si todavía estás un poco confundido!

## Su alcance

El siguiente error más común sobre el significado de `this` es que de alguna manera se refiere al alcance de la función. Es una pregunta difícil, porque en cierto sentido hay algo de verdad, pero en el otro sentido, es bastante equivocado.

Para ser claro, `this` no se refiere, en modo alguno, al **ámbito léxico** de una función. Es cierto que internamente, el alcance es como un objeto con propiedades para cada uno de los identificadores disponibles. Pero el "objeto" de alcance no es accesible al código JavaScript. Es una parte interna de la implementación del Motor.

Considere el código que intenta (y falla!) cruzar el límite y usa `this` para referirse implícitamente al ámbito léxico de una función:

```javascript
function foo() {
    var a = 2;
    this.bar();
}

function bar() {
    console.log( this.a );
}

foo(); //undefined
```

Hay más de un error en este fragmento. Aunque puede parecer artificial, el código que ves es una destilación del código real del mundo real que se ha intercambiado en los foros públicos de ayuda de la comunidad. Es una ilustración maravillosa (si no triste) de lo equivocados que pueden ser estos supuestos sobre `this`.

En primer lugar, se intenta hacer referencia a la función `bar()` a través de `this.bar()`. Es casi ciertamente un accidente que funcione, pero vamos a explicar el cómo en breve. La forma más natural de haber invocado `bar()` habría sido omitir la declaración `this`. Y sólo hacer una referencia léxica al identificador.

Sin embargo, el desarrollador que escribe este código intenta usar `this` para crear un puente entre los ámbitos léxicos de `foo()` y `bar()`, de modo que `bar()` tenga acceso a la variable `a` en el ámbito interno de `foo()`. **Ningún puente es posible**. No puedes usar esta referencia para buscar algo en un ámbito léxico. No es posible.

Cada vez que se sientan tratando de mezclar perspectivas de alcance léxico con `this`, recuerde: no hay puente.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://daniel-morales.gitbook.io/javascript-avanzado-en-espanol/iii-this-and-object-prototypes/1-this-o-that/12-confusiones.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
