Significato di “this” nei moduli e nelle funzioni node.js

Ho un file JavaScript che viene caricato da 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" ); 

La mia domanda è: this in var a = this; è un object vuoto mentre this istruzioni nelle funzioni sono ombre dell’object globale node.js. So che this parola chiave è diversa nelle funzioni, ma non capisco perché prima this non è uguale a globale e this in funzioni è uguale a globale.

In che modo node.js viene iniettato a global negli ambiti della funzione e perché non lo inietta nell’ambito del modulo?

Ecco alcuni fatti fondamentali che devi capire per chiarire la situazione:

  • Nel codice di livello superiore in un modulo Node, this è equivalente a module.exports . Questo è l’object vuoto che vedi.

  • Quando si utilizza this all’interno di una funzione, il valore di this viene determinato di nuovo prima di ogni esecuzione della funzione e il suo valore è determinato dal modo in cui viene eseguita la funzione . Ciò significa che due invocazioni dell’object esatto della stessa funzione potrebbero avere valori diversi se i meccanismi di aFunction() sono diversi (ad esempio aFunction() vs. aFunction.call(newThis) vs. emitter.addEventListener("someEvent", aFunction); etc .) Nel tuo caso, aFunction() in modalità non rigida esegue la funzione con this set sull’object globale.

  • Quando i file JavaScript sono require come moduli Node, il motore del nodo esegue il codice del modulo all’interno di una funzione wrapper. Quella funzione di wrapping dei moduli viene invocata con un set su module.exports . (Ricorda, sopra, una funzione può essere eseguita con un valore di this valore.)

Pertanto, si ottengono valori diversi perché ognuno di essi risiede in una funzione diversa: la prima è all’interno della funzione modulo-wrapper creata dal nodo e la seconda è all’interno di una aFunction .

Per capire questo, è necessario capire che Node.js in realtà avvolge il codice del modulo in una funzione, come questa

 (function (exports, require, module, __filename, __dirname) { var test = function(){ console.log('From test: ' + this); }; console.log(this); test(); }); 

Una spiegazione dettagliata può essere trovata in questa risposta .


Ora, questa funzione avvolta viene effettivamente invocata in questo modo

 var args = [self.exports, require, self, filename, dirname]; return compiledWrapper.apply(self.exports, args); 

Quindi, this , a livello di modulo, è in realtà l’object exports .

Puoi confermarlo così

 console.log(this, this === module.exports); // {} true 

È perché l’object globale predefinito in un modulo Node.js è l’object exports , e stai chiamando test() che non lo specifica. Nel JS tradizionale, this punta all’object globale, con l’ use strict , this sarà nullo.

this può indicare tutto, dipende solo da come lo chiami.

  • test() : utilizza l’object globale ( exports ) come this , a meno che non sia in modalità rigorosa, dove this sarà nullo;
  • test.call({}) o test.apply({}) : stai specificando cosa usare come this (il primo parametro)
  • var obj = {testRef: test}; obj.testRef() var obj = {testRef: test}; obj.testRef() : this è impostato a sinistra di . , cioè, obj

Contrastare la risposta di thefourtheye

È vero che this nel livello più alto del modulo è l’ exports , ma questo non significa necessariamente che this test() all’interno test() indicherà anche la stessa cosa da dove è stato chiamato.


Tentando di dimostrare che this e l’object globale indicano entrambe le exports

  myGLobal = 5; this.myGlobal; // 5