9
var foo = (function(){ 
    var x = "bar"; 
    return function(){ 
    console.log(x); 
    }; 
})(); 

console.log(foo.toString()); // function() {console.log(x);} 
(foo)(); // 'bar' 
eval('(' + foo.toString()+')()')); // error: x is undefined 

C'è una tecnica per la risoluzione (modifica) di una funzione, in modo da riferimenti dal campo di applicazione esterno diventano riferimenti locali, come:risolvere i riferimenti esterno portata in una funzione javascript per la serializzazione

function() {console.log(x);} 

diventa:

function() {console.log("bar");} 

La funzione può ora essere modificata e trasportata su una rete ed eseguita in un altro runtime.

Forse si potrebbe analizzare la funzione in un Abstract Syntax Tree e quindi modificarlo? Il riferimento sarà sempre fuori portata (non disponibile), giusto?

Obiettivo:

sto serializzazione una funzione di filtro da un runtime nodo ad un runtime postgresql plv8. In questo momento la funzione filtro ha un'interfaccia: dbClient.filter ((row, age) => row.age> age), ageFromOuterScope) .then (matches => ...)

Voglio interfaccia dbClient.filter ((row) => row.age> age)). then (matches => ...), dove age è un riferimento dall'ambito esterno.

Aggiornamento:

posso solo immaginare una soluzione. Analizzare la funzione, individuare i riferimenti alle variabili fuori della funzione, e quindi riscrivere la funzione originale:

function(row) { 
    return row.age > age 
} 

Per:

function(row, age) { 
    return row.age > age 
} 

variabili rilevate dovrebbero essere aggiunti a una stringa che rappresenta una matrice, come :

var arrayString = '[age]' 

E poi eval la stringa:

var functionArgs = eval(arrayString) 

E infine:

dbClient.filter(modifiedFunction, ...functionArgs).then(matches => ...) 
+0

La maggior parte delle volte tali variabili vengono modificate in fase di runtime, quindi tali conversioni cambierebbero il comportamento del codice. –

+1

Due commenti: uno, questo è fuori tema per Stack Overflow dal momento che richiede una libreria. Due, non è così che funziona lo scoping in Javascript, né dovrebbe, ed è per questo che non funziona per te. Dal momento che non funziona in questo modo, in che modo una tecnica potrebbe prevedere correttamente come prendere questa decisione? Questo a sua volta rende la domanda ampia per Stack Overflow. –

+0

Ho modificato la domanda. Che ne dici di usare AST? – Jacob

risposta

0

ho corse foo del codebox superiore attraverso di Google Closure Compiler, e mi ha dato questo:

var foo=function(){return function(){console.log("bar")}}();foo; 

non è esattamente ciò che si vuole, ma si può ottenere quello che vuoi da lì usando eval() e/o toString() mentre stai già armeggiando.

Non so quanto questo sia robusto, e rende altri maneggiamenti di codice, ma per il semplice tipo di funzioni che si mostrano, sembra che le primitive non ripetute in linea consistenti compaiano nel codice.

1

È possibile associare la x all'oggetto funzione stesso.

var foo = (function(){ 
 
    var x = "bar"; 
 
    return function(){ 
 
    this.x = x; 
 
    console.log(this.x); 
 
    }; 
 
})(); 
 

 
(foo)() // 'bar' 
 

 
console.log(foo.toString()); // 'function() { this.x = x; console.log(this.x) }' 
 

 
eval('(' + foo.toString()+')()'); // 'bar'

1

per esporre la variabile privata al di fuori del campo di applicazione è necessario un altro funzione nell'ambito di applicazione che riscrive la descrizione del metodo restituito da toString. Quindi si utilizza quella funzione anziché toString per recuperare la descrizione del metodo.

var foo = (function(){ 
    var x = "bar"; 

    var f = function(){ 
    console.log(x); 
    }; 

    f.decl = function() { 
     return f.toString().replace("(x)", "(\""+x+"\")"); 
    } 

    return f; 

})(); 

console.log(foo.decl()); // function() {console.log("bar");} 

eval("("+foo.decl()+")()"); // bar 
Problemi correlati