Significado de "esto" en los módulos y funciones de node.js
Tengo un archivo JavaScript cargado por require
.
// loaded by require()
var a = this; // "this" is an empty object
this.anObject = {name:"An object"};
var aFunction = function() {
var innerThis = this; // "this" is node global object
};
aFunction();
(function(anyParameter){
console.log(anyParameter.anObject);
})(
this // "this" is same having anObject. Not "global"
);
Mi pregunta es: this
en var a = this;
es un objeto vacío, mientras que this
las declaraciones en funciones son sombras del objeto global de node.js. Sé que this
la palabra clave es diferente en funciones, pero no podía entender por qué primero this
no es igual a global y this
en funciones es igual a global.
¿Cómo se inyecta node.js global
en this
los alcances de las funciones y por qué no lo inyecta en el alcance del módulo?
Aquí hay algunos hechos fundamentales que debe comprender para aclarar la situación:
En el código de nivel superior de un módulo de Nodo,
this
equivale amodule.exports
. Ese es el objeto vacío que ves.Cuando se usa
this
dentro de una función, el valor dethis
se determina nuevamente antes de cada ejecución de la función, y su valor se determina por cómo se ejecuta la función . Esto significa que dos invocaciones del mismo objeto de función podrían tenerthis
valores diferentes si los mecanismos de invocación son diferentes (por ejemplo,aFunction()
vs.aFunction.call(newThis)
vs.emitter.addEventListener("someEvent", aFunction);
, etc.). En su caso,aFunction()
en modo no estricto ejecuta la funciónthis
configurada en el objeto global.Cuando los archivos JavaScript se
require
guardan como módulos de Node, el motor de Node ejecuta el código del módulo dentro de una función contenedora. Esa función de ajuste de módulo se invoca con unthis
conjunto enmodule.exports
. (Recuerde, arriba, una función se puede ejecutar con unthis
valor arbitrario).
Por lo tanto, obtienes this
valores diferentes porque cada uno this
reside dentro de una función diferente: el primero está dentro de la función contenedora del módulo creada por el nodo y el segundo está dentro de aFunction
.
Para comprender esto, debe comprender que Node.js en realidad envuelve el código de su módulo en una función, como esta
(function (exports, require, module, __filename, __dirname) {
var test = function(){
console.log('From test: ' + this);
};
console.log(this);
test();
});
Se puede encontrar una explicación detallada en esta respuesta .
Ahora, esta función envuelta se invoca así
var args = [self.exports, require, self, filename, dirname];
return compiledWrapper.apply(self.exports, args);
Entonces, this
a nivel de módulo, es en realidad el exports
objeto.
Puedes confirmarlo así.
console.log(this, this === module.exports);
// {} true