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 

Есть ли метод для разрешения (модификации) функции, так что ссылки из внешней области стали локальными ссылками, такие как:разрешение ссылок на внешнюю области применения в яваскрипте функции для сериализации

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

становится:

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

Теперь эта функция может быть сжата и транспортирована по сети и выполнена в другой среде.

Возможно, можно проанализировать функцию в абстрактном дереве синтаксиса, а затем изменить ее? Ссылка всегда будет недоступна (не доступно), правильно?

Цель:

Я сериализация функции фильтра от выполнения узла к PostgreSQL plv8 выполнению. Прямо сейчас функция фильтра имеет интерфейс: dbClient.filter ((строка, возраст) => row.age> возраст), ageFromOuterScope). Then (matches => ...)

Я хочу интерфейс dbClient.filter ((row) => row.age> age)), затем (matches => ...), где age является ссылкой из внешней области.

Update:

Я могу только представить себе одно решение. Анализ функции обнаружения ссылки на переменные вне функции, а затем переписать исходную функцию:

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

To:

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

Обнаруженные переменные должны также быть добавлены в строку, которые представляют собой массив, как :

var arrayString = '[age]' 

А затем Eval строку:

var functionArgs = eval(arrayString) 

И наконец:

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

В большинстве случаев такие переменные изменяются во время выполнения, поэтому такие преобразования могут изменить поведение кода. –

+1

Два комментария: один, это не тема для переполнения стека, поскольку он запрашивает библиотеку. Во-вторых, это не то, как обзор работает в Javascript, и не должен, поэтому он не работает для вас. Поскольку это не работает таким образом, как техника правильно предсказывает, как принять это решение? Это, в свою очередь, делает вопрос широким для Stack Overflow. –

+0

Я изменил вопрос. Как насчет использования АСТ? – Jacob

ответ

0

Я побежал Foo ваш топ CodeBox через Google, Closure Compiler, и он дал мне это:

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

не ТОЧНО, что вы хотите, но вы можете получить то, что вы хотите оттуда используя eval() и/или toString(), как вы уже занимались.

Я не знаю, насколько это здорово, и это делает другие кодовые искажения, но для простых видов функций, которые вы показываете, это похоже на последовательно встроенные не повторяющиеся примитивы, появляющиеся в коде.

1

Вы можете привязать x к самому объекту функции.

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

Выставить приватную переменную вне области, которую нужно другой функции в пределах области, которая переписывает описание метода, возвращаемый ToString. Затем вы используете эту функцию вместо toString для извлечения описания метода.

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