Bienvenido, soy Miguel y hoy les traigo otro tutorial.
Para comprender «this», debemos verificar nuestra comprensión de los fundamentos de JavaScript. ¿Sé qué es un «contexto de ejecución» y una «invocación»? Como resumen, el «contexto de ejecución» es el entorno en el que se invoca el bloque de código. Este concepto es extremadamente importante porque el valor de «this» es el contexto de ejecución. «Invocación» es cuando se utilizan paréntesis para llamar a una función.
El valor de «this» está determinado por el contexto de ejecución actual de la función que se invoca. A menudo, el contexto de ejecución es el objeto que llamó a la función. JavaScript tiene cuatro tipos de invocación de funciones y un tipo de definición de función que afectan el valor de «this». Resumiré los valores de “this” y luego entraré en más detalle a continuación.
- Invocación de función | myFunction (): el contexto de ejecución de funciones es el objeto global, por lo que «this» se refiere al objeto global.
- Invocación de método | myObject.myMethod (): un método es una función que se almacena como una propiedad de un objeto. Como tal, invocamos myMethod en el contexto de myObject. En consecuencia, «this» se refiere a myObject.
- Invocación de constructor | new MyClass (): Cuando se invoca la función de clase, JavaScript crea un nuevo objeto y establece el contexto de ejecución para el nuevo objeto, por lo que «this» se refiere al nuevo objeto.
- Invocación explícita | myFunction.call (myObject): todas las funciones tienen los métodos .call, .apply y .bind. Usamos estos métodos para especificar el valor de «this».
- Definición de función de flecha | myFunction (): “this” se refiere al contexto donde se definió la función de flecha.
Índice
Invocaciones de funciones
Las funciones se invocan en el contexto de ejecución global. Por lo tanto, cuando se invoca una función (¡no un método que pertenece a un objeto!), «This» se refiere al objeto global. Cabe señalar que myObject.myFunction se considera una invocación de método en lugar de una invocación de función .this
function myFunction() { console.log(this); }myFunction(); // returns the Global Object
Invocaciones de métodos
Por definición, un método es una función que se almacena como propiedad de un objeto. Ejemplos de métodos son myObject.myFunction o Array.map. Cuando llamamos a un método con referencia al objeto que lo posee, el método se invoca en el contexto de ese objeto. En el siguiente ejemplo, myFunction es una propiedad de myObject. Por lo tanto, el contexto de ejecución es myObject y «this» se refiere a myObject.
const myObject = { a: 1, b: 2, myFunction: function () { console.log(this); }, };myObject.myFunction(); //prints myObject
Detengámonos y probemos nuestro conocimiento de los contextos de ejecución. Si tenemos una función dentro de myFunction llamada innerFunction, ¿cuál sería el valor de «this» en innerFunction? Si adivinó que se refiere al objeto global, estaría en lo cierto. Entendamos por qué “this” en innerFunction se referiría al objeto global. Sabemos que myFunction es un método de myObject, por lo que cuando se llama a myFunction, el contexto de ejecución es myObject. Por el contrario, ¿innerFunction es un método de myFunction? No. innerFunction es simplemente una función que se define dentro de myFunction pero no es una propiedad / método de myFunction. Por lo tanto, cuando se llama a innerFunction, su contexto de ejecución es el objeto global.
const myObject = { a: 1, b: 2, myFunction: function () { function innerFunction() { console.log(this); //prints the global object } innerFunction(); }, };myObject.myFunction();
Invocación de constructor / clase
Cuando invocamos una función de clase usando la palabra clave «new», JavaScript crea un nuevo objeto y establece el contexto de ejecución para el nuevo objeto. Ahora, la función de constructor puede establecer las propiedades y métodos del nuevo objeto usando «this». Como puede ver en el siguiente ejemplo, el «perro» que creamos tiene dos propiedades que fueron establecidas por la función constructora nombre: ‘Spot’, peso: 20.
class Dog { constructor(name, weight) { this.name = name; this.weight = weight; } speak() { return `$ {this.name} says woof.`; } }const dog = new Dog('Spot', 20); console.log(dog); console.log(dog.name); console.log(dog.speak());
Invocación explícita
Cuando necesitamos especificar el valor de «this», usamos los métodos call (), apply () o bind (). La principal diferencia entre estos métodos es que bind () devoluciones una nueva función mientras que call () y apply() invocar la función dada.
const myObject = { name: 'myName' }; function myFunction(string) { console.log(string + this.name); }myFunction.call(myObject, 'Hello '); // => 'Hello myName' myFunction.apply(myObject, ['Hello ']); // => 'Hello myName'
En el método getNumber en object1 a continuación, «this» se establece implícitamente en object1 porque getNumber es un método de object1. Sin embargo, usamos el método bind para cambiar la referencia de «this» de object1 a object2.
const object1 = { myNumber: 1, getNumber: function () { return this.myNumber; }, };const object2 = { myNumber: 2, };console.log(object1.getNumber()); // 1 const boundNumber = object1.getNumber.bind(object2); console.log(boundNumber()); // 2
Funciones de flecha
A diferencia de otras funciones y métodos, las funciones de flecha heredan el valor de «this» de su padre. En el siguiente ejemplo, el padre es el objeto de ventana, por lo que «this» se refiere al objeto de ventana.
const myArrowFunction = () => { console.log(this); };myArrowFunction(); // window object
Gotcha
Digamos que creamos una nueva variable, myVariable, en el ámbito global y la configuramos en myObject.getNumber. Tenga en cuenta que getNumber es un método de myObject. Luego, invocamos myVariable. ¿Cuál deberíamos esperar que el valor de «this» esté dentro de myVariable? Bazinga, «this» se refiere al objeto global. ¿Por qué? Cuando se produce una invocación sin una referencia a un objeto, JavaScript asume una invocación de función, en cuyo caso el contexto de ejecución es el objeto global. Por tanto, «this» se refiere al objeto global. Como se muestra en el siguiente ejemplo, el valor de this.myNumber no está definido porque «this» se refiere al objeto global.
const myObject = { myNumber: 1, getNumber: function () { return this.myNumber; }, };const myVariable = myObject.getNumber; console.log(myVariable()); // undefined
Alternativamente, si invoca directamente myObject.getNumber (), devolverá 1 porque getNumber () mantendrá su contexto en myObject.
const myObject = { myNumber: 1, getNumber: function () { return this.myNumber; }, }; console.log(myObject.getNumber()); // 1
Gracias por leer.
Añadir comentario