Quanto deve andare lontano l'incapsulamento in JavaScript?

4

Ho una variabile che voglio usare in una sola funzione. Posso scrivere il mio codice in questo modo:

var theAnswerToLife = 42

var multiplyIt = function(x) {
  return ++theAnswerToLife * x
}

Ho alcune altre funzioni in quel file, che non usano quella variabile. Pertanto, al fine di limitare l'accesso a tale variabile solo alla funzione multiplyIt , potrei inserirlo in un IIFE:

var multiplyIt = (function() {
  var theAnswerToLife = 42

  return function(x) {
    return ++theAnswerToLife * x
  }
}())

Ora quella variabile è disponibile solo per la funzione interna. Tale incapsulamento ha ovviamente senso quando ho più variabili, ma vale la pena con una sola variabile? La sintassi IIFE è piuttosto pesante e, in un codice più complesso, potrei finire per avere come tre IFFE nidificati.

Come mantenere l'equilibrio tra incapsulamento e leggibilità del codice? Dov'è il limite?

Il mio ambiente è Node.js, quindi una variabile definita all'esterno di una funzione non sarà globale, ma sarà disponibile solo nell'ambito del modulo.

    
posta Michał Perłakowski 01.05.2016 - 19:15
fonte

2 risposte

3

Dato una variabile che deve avere uno scope oltre una singola chiamata di funzione, ma accessibile solo da una funzione, credo che sia giusto non introdurre un nuovo scope solo per quella funzione finché non lo fai t rendere la variabile globale .

In altre parole, inserisco questa variabile nell'ambito del modulo . Dovresti già disporre di una sorta di sistema modulare che impedisce l'accesso a variabili di livello superiore da parte di altri moduli, a meno che non venga esportato esplicitamente. Ciò potrebbe significare il tradizionale pattern del modulo IIFE, o i moduli common.js o qualche altro formato, ma qualunque esso sia dovrebbe introdurre un nuovo scope non globale per ogni modulo, quindi basta usare quell'ambito quando un IIFE addizionale sembra eccessivo.

    
risposta data 01.05.2016 - 22:49
fonte
0

Se il tuo obiettivo è limitare l'ambito variabile, stai rendendo il problema più difficile del necessario.

Considera questa funzione che raggiunge lo stesso obiettivo con un ambito molto più limitato, sia per le variabili interne che per la complessità della funzione:

function doIt(x) {
  var theAnswer = 42;

  return x * 42;
}

Fa la stessa cosa che fa il tuo, ma senza la complessità aggiuntiva di un Clojure o IIFE (Esecuzione funzione immediatamente richiamata) . Inoltre, non espone theAnswer al pool di variabili globali.

Chiamarlo con questo codice provocherà un errore sull'ultima riga:

var results = document.getElementById("results");
results.innerText = "Function(3): " + doIt(3); 
results.innerText += ", theAnswer: " + theAnswer;
    
risposta data 01.05.2016 - 20:52
fonte

Leggi altre domande sui tag