Chiamare una funzione "locale" all'interno di module.exports da un'altra funzione in module.exports?


327

Come si chiama una funzione all'interno di un'altra funzione in una module.exportsdichiarazione?

app.js
var bla = require('./bla.js');
console.log(bla.bar());
bla.js
module.exports = {

  foo: function (req, res, next) {
    return ('foo');
  },

  bar: function(req, res, next) {
    this.foo();
  }

}

Sto provando ad accedere alla funzione foodall'interno della funzione bare sto ottenendo:

TypeError: Object # non ha un metodo 'pippo'

Se cambio this.foo()a solo foo()ottengo:

Errore di riferimento: foo non è definito


4
Ho testato il tuo codice e non ho errori. La funzione bar restituisce un indefinito perché non ha un'istruzione return. Sei sicuro di provare correttamente?
— Ferchi,

1
Testato nella versione nodo v8.12.0e non genera più l'errore. barnon ha dichiarazioni di console.log(bla.bar())undefined
— reso,

Risposte:


351

Cambia this.foo()inmodule.exports.foo()


1
@NamNguyen Calling exports.foo()sembra un po 'imbarazzante e difficile da leggere.
— Afshin Mehrabani,

4
Penso che sia meglio della risposta accettata. Se si definiscono funzioni al di fuori dell'ambito delle esportazioni, si aggiunge un ulteriore livello di riferimento indiretto, e sebbene possa essere desiderabile a volte, rende più complicato, refactoring, ad esempio rinominare la funzione, trovare utilizzo della funzione, ecc.
— Pierre Henry,

1
una risposta diretta alla domanda
— Kermit_ice_tea

8
module.exports.foo()e exports.foo()non funziona per me con Node.js v5.8.0.
— tra il

14
exports.foo () non funziona ma module.exports.foo () funziona con NodeJS v6.9.1
— R. Canser Yanbakan il

191

Potresti dichiarare le tue funzioni al di fuori del module.exportsblocco.

var foo = function (req, res, next) {
  return ('foo');
}

var bar = function (req, res, next) {
  return foo();
}

Poi:

module.exports = {
  foo: foo,
  bar: bar
}

11
e se volessi accedere alle proprietà dell'oggetto dal metodo?
— Rockstar5645,

1
Sto ottenendo TypeError: yourClass.youMethod non è una funzione quando l'ho fatto. Sto usando il nodo versione 6.9.1. Devi avere una dichiarazione di reso? Non ho dichiarazioni di ritorno poiché tutto il mio codice è asincrono nelle funzioni.
— Brett Mathe,

1
Bel confronto di stili diversi - gist.github.com/kimmobrunfeldt/10848413
— Tadas V.

Implementazione molto bella! +1
— realnsleo

3
O, più concisamente, usando ES6,module.exports = { foo, bar, }
— Let Me Tink About It

118

Puoi anche farlo per renderlo più conciso e leggibile. Questo è quello che ho visto fare in molti dei moduli open source ben scritti:

var self = module.exports = {

  foo: function (req, res, next) {
    return ('foo');
  },

  bar: function(req, res, next) {
    self.foo();
  }

}

Questa versione di Node.js è specifica? Sto provando questo con v5.8.0 e sta registrando indefinito.
— tra il

1
@doublejosh Hai ... hai letto la domanda? Si sta chiedendo come si chiama una funzione esportata da un'altra. Non ha nulla a che fare con le restrizioni di accesso.
— Finanzi la causa di Monica

1
Sì, l'ho letto, per favore rileggi. Questa risposta fa esportare foo () con il modulo, che va contro il punto di una funzione "locale" chiamata solo all'interno del modulo.
— doublejosh

66

È inoltre possibile salvare un riferimento all'ambito globale del modulo al di fuori della definizione (module.) Exports.somemodule:

var _this = this;

exports.somefunction = function() {
   console.log('hello');
}

exports.someotherfunction = function() {
   _this.somefunction();
}

È una soluzione più pulita!
— IvanZh,

non c'è bisogno di questo e puoi semplicemente usarlo dove ne hai bisogno
— Yuki

usato thisdirettamente, non è necessario dichiarare_this
— Dario

1
Quel suggerimento è utile una volta thisnon è più il diritto this. (Promesse e callback)
— Andrew McOlash

Mi piace questa soluzione la migliore perché fornisce anche un esempio di scoping nei moduli NodeJS.
— miguelmorin,

40

Un'altra opzione, e più vicina allo stile originale dell'OP, è quella di mettere l'oggetto che si desidera esportare in una variabile e fare riferimento a quella variabile per effettuare chiamate ad altri metodi nell'oggetto. Puoi quindi esportare quella variabile e sei a posto.

var self = {
  foo: function (req, res, next) {
    return ('foo');
  },
  bar: function (req, res, next) {
    return self.foo();
  }
};
module.exports = self;

25
const Service = {
  foo: (a, b) => a + b,
  bar: (a, b) => Service.foo(a, b) * b
}

module.exports = Service

3
Ciò è particolarmente utilizzabile perché il tuo codice è presente Service.foo()e anche il tuo codice client chiamerà Service.foo()con lo stesso nome.
— Vince Bowdren,

Questa è una risposta perfetta!
— Jayant Varshney,

16

A partire da Node.js versione 13 è possibile sfruttare i moduli ES6 .

export function foo() {
    return 'foo';
}

export function bar() {
    return foo();
}

Seguendo l'approccio di classe:

class MyClass {

    foo() {
        return 'foo';
    }

    bar() {
        return this.foo();
    }
}

module.exports = new MyClass();

Ciò creerà un'istanza della classe una sola volta, a causa della memorizzazione nella cache del modulo del nodo:
https://nodejs.org/api/modules.html#modules_caching


e come si chiama un metodo statico con questo approccio?
— Plixxer,

@CodeofGod Basta chiamarlo come si chiamerebbe qualsiasi altro metodo statico. In questo caso, se fooera statico si chiama da dentro barin questo modo: MyClass.foo().
— m.spyratos,

sì, lo capisco, ma come lo chiameresti da un controller che lo sta importando come ... const oAccounts = require ("...");
— Plixxer,

È possibile esportare la classe effettiva, non un'istanza della classe. In questo modo puoi usare i suoi metodi statici. Se poi devi usare i suoi metodi di istanza, dovrai istanziare la classe nel tuo controller.
— m.spyratos,

6

Per risolvere il tuo problema, ho apportato alcune modifiche a bla.js e funziona,

var foo= function (req, res, next) {
  console.log('inside foo');
  return ("foo");
}

var  bar= function(req, res, next) {
  this.foo();
}
module.exports = {bar,foo};

e nessuna modifica in app.js

var bla = require('./bla.js');
console.log(bla.bar());

1
Nella barra delle funzioni, this.foo () non funziona ... deve essere foo ()
— Falcoa,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.