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 

ist eine Technik für die Lösung (Modifikation) mit einer Funktion, so Referenzen von äußeren Umfang lokale Referenzen werden, wie:Auflösen Außen-scope Referenzen in einer JavaScript-Funktion für die Serialisierung

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

wird:

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

Die Funktion kann jetzt über ein Netzwerk beschriftet und transportiert werden und in einer anderen Laufzeit ausgeführt werden.

Vielleicht könnte man die Funktion zu einem Abstract Syntax Tree analysieren und dann modifizieren? Die Referenz ist immer außerhalb des gültigen Bereichs (nicht verfügbar), oder?

Ziel:

mir eine Filterfunktion von einem Knoten zu einer Laufzeit-postgresql plv8 Laufzeit Serialisierung. Jetzt hat die Filterfunktion die Schnittstelle: dbClient.filter ((row, age) => row.age> age), ageFromOuterScope) .dann (entspricht => ...)

Ich möchte die Schnittstelle dbClient.filter ((row) => row.age> age)). then (matches => ...), wobei das Alter eine Referenz aus dem äußeren Bereich ist.

Update:

Ich kann nur eine Lösung vorstellen. Analysieren Sie die Funktion erkennen Verweise auf Variablen außerhalb der Funktion, und dann die ursprüngliche Funktion umschreiben:

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

An:

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

Erkannt Variablen auch in einen String hinzugefügt werden soll, die ein Array darstellen, wie :

var arrayString = '[age]' 

Und eval dann die Zeichenfolge:

var functionArgs = eval(arrayString) 

Und schließlich:

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

In den meisten Fällen werden solche Variablen zur Laufzeit geändert, sodass solche Konvertierungen das Verhalten des Codes ändern würden. –

+1

Zwei Kommentare: Erstens, dies ist ein Thema für Stack Overflow, da es eine Bibliothek anfordert. Zweitens funktioniert das Scoping nicht in Javascript, noch sollte es funktionieren, weshalb es nicht für Sie funktioniert. Da es auf diese Art nicht funktioniert, wie würde eine Technik richtig vorhersagen, wie man diese Entscheidung trifft? Dies wiederum wirft die Frage nach Stack Overflow auf. –

+0

Ich änderte die Frage. Wie wäre es mit AST? – Jacob

Antwort

0

lief ich Ihre Top codebox die foo durch die Google-Closure Compiler, und es gab mir dies:

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

nicht genau, was Sie wollen, aber Sie können, was Sie wollen von dort mit eval() und/oder toString(), wie Sie bereits mit basteln.

Ich weiß nicht, wie robust das ist, und es macht andere Code-Mängel, aber für die einfache Art von Funktionen, die Sie zeigen, scheint es immer wieder inline-nicht wiederholt Grundelemente in Code erscheinen.

1

Sie können das x an das Funktionsobjekt selbst binden.

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

Um die private Variable außerhalb des Bereichs Sie im Rahmen einer anderen Funktion benötigen aussetzen, der die Methode Beschreibung von toString umschreibt. Dann verwenden Sie diese Funktion anstelle von toString, um die Methodenbeschreibung abzurufen.

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