Prefacio
Hay mucha informaci贸n en Internet sobre c贸mo funciona esto, pero todo el tiempo no tuve suficiente literalmente un poquito para entenderlo por completo.
Recientemente, sin embargo, seg煤n me parece, hice esto y me gustar铆a compartirlo con ustedes.
Sin muchas palabras
Cubriremos ejemplos simples y complejos, para que todos est茅n interesados.
Hay dos puntos principales que veremos:
(1) Para las funciones declaradas mediante la funci贸n () {}, esto se calcula en el momento de la llamada.
(2) Para las funciones de flecha, esto se define cuando se crea la funci贸n.
Comencemos con algunos ejemplos simples.
function globalFunc() {
console.log(this);
}
const globalArrowFunc = () => {
// , this - window/undefined
// , use strict this === undefined
console.log(this);
}
globalFunc(); // undefined
globalArrowFunc(); // undefined
驴Qu茅 pasa si agregamos estas funciones al objeto:
const cat = {
name: 'Pirate',
globalFunc,
globalArrowFunc
};
cat.globalFunc(); // { name: 'Pirate', ... }
cat.globalArrowFunc(); // undefined
Vamos a averiguarlo.
Llamar a cat.globalFunc () nos devolvi贸 un objeto cat. Para facilitar la comprensi贸n, puede pensar en ello as铆 "esto, cuando se llaman funciones declaradas a trav茅s de la funci贸n () {}, ser谩 igual al objeto antes del punto".
Entonces, 驴por qu茅 cat.globalArrowFunc () regres贸 indefinido para nosotros? El hecho es que el valor this para una funci贸n de flecha se determina en el momento de su creaci贸n, y cuando lo creamos, este valor no estaba definido.
Ahora creemos un objeto con un par de m茅todos:
const dog = {
name: 'Viking',
//
//
localFunc: function() {
console.log(this);
},
localArrowFunc: () => {
console.log(this);
}
};
dog.localFunc(); // { name: 'Viking', ... }
dog.localArrowFunc(); // undefind
驴Porqu茅 es eso?
dog.localFunc () - porque el objeto antes del punto dog.
dog.localArrowFunc () - porque dentro del objeto tambi茅n es un objeto global, lo que significa que no estamos definidos.
Compliquemos un poco nuestro ejemplo.
const dog = {
name: 'Viking',
localFunc: function() {
const arrowFuncInLocalFunc = () => {
console.log(this);
};
function funcInLocalFunc() {
console.log(this);
};
arrowFuncInLocalFunc(); // 1
funcInLocalFunc(); // 2
},
localArrowFunc: () => {
const arrowFuncInLocalArrowFunc = () => {
console.log(this);
};
function funcInLocalArrowFunc() {
console.log(this);
};
arrowFuncInLocalArrowFunc(); // 3
funcInLocalArrowFunc(); // 4
}
};
dog.localFunc();
// 1 - { name: 'Viking', ... }
// 2 - undefind
dog.localArrowFunc();
// 3 - undefind
// 4 - undefind
隆Vamos a resolverlo!
(1) arrowFuncInLocalFunc () // {nombre: 'Viking',鈥
驴Por qu茅 sucede esto?
Porque cuando creamos el objeto, lo escribimos en la funci贸n localFunc. Y, como recordamos de los ejemplos anteriores, para ella este es el objeto antes del punto, es decir, {nombre: 'Viking', ...}. Ahora hablemos de la funci贸n arrowFuncInLocalFunc en s铆: se crea inmediatamente cuando se llama a localFunc y recuerda el valor this que estaba en el lugar de su creaci贸n. As铆 obtenemos que arrowFuncInLocalFunc nos devuelve {nombre: 'Viking',鈥.
(2) funcInLocalFunc () // undefind
驴 Por qu茅 sucede esto?
Como dijimos antes, para las funciones declaradas mediante function () {}, este valor se determina en el momento de la llamada y es igual al objeto antes del punto. En este caso, no tenemos un objeto delante del punto, lo que significa que este es un objeto global o, en nuestro caso, indefinido.
(3) arrowFuncInLocalArrowFunc () // undefined
驴Por qu茅 sucede esto?
Este ejemplo es muy similar a (1), solo nuestra funci贸n arrowFuncInLocalArrowFunc se crea dentro de la misma funci贸n de flecha. Tambi茅n recordamos que las funciones de flecha en el momento de su declaraci贸n escriben en este valor desde su entorno. Sin embargo, nuestra funci贸n se cre贸 dentro de localArrowFunc, por lo que esto no est谩 definido. Esto significa que para arrowFuncInLocalArrowFunc esto no estar谩 definido.
(4) funcInLocalArrowFunc () // indefinido
驴Por qu茅 sucede esto?
Exactamente la misma raz贸n que en (2) para funcInLocalFunc
Veamos otro ejemplo:
const cat = {
name: 'Tom',
getFuncWithTomName: function() {
return () => {
console.log(this.name);
}
}
};
const mouse = {
name: 'Jerry',
logName: cat.getFuncWithTomName()
};
mouse.logName(); // Tom o_O !?
Esto se debe a que getFuncWithTomName crea y devuelve una funci贸n de flecha, y cuando se crea la funci贸n de flecha, es la misma que la de getFuncWithTomName. Y para getFuncWithTomName, este es el objeto antes de dot (cat).
Total
El contexto de las funciones de flecha se determina cuando se crean.
El contexto de la funci贸n () {} se define cuando se llaman y es igual al objeto antes del punto.