2015-06-18 2 views
2

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

Простой пример:

function foo(a,b) { 
    return function(x) { 
     //doing something with values of a and b, for example: 
     return a*x + b; 
    } 
} 

Так что, если я делаю:

var c = foo(2,3); 
var d = foo(4,5); 

с и d будет выглядеть следующим образом:

c: function(x) { 
    return 2*x + 3; 
} 
d: function(x) { 
    return 4*x + 5; 
} 

Я хочу Foo() для замены переменных a, b с их значениями перед возвратом новой функции. Поэтому c и d не нужно ссылаться на некоторые вары вне себя.

Я работаю с CasperJS и пытаюсь динамически создавать функции, которые будут выполняться casper.evaluate(), который изолирует исполняемые функции. Вот почему он не будет работать так, как описано в примере.

Любые идеи, как это решить? Спасибо большое!

EDIT:

Зачем мне это нужно? Я пытаюсь написать абстрактный гусеничный шасси с CasperJS. Таким образом, существует «основная» -функция, которая обращается к объектной переменной (var site = {...}), содержащей несколько функций, которые casper.evaluate() принимает в качестве аргументов один за другим. Эти функции выполняются изолированными на открытой веб-странице, поэтому они не могут получить доступ к каким-либо переменным за пределами веб-страницы. Они могут делать совсем другие вещи, но в основном они ищут один вид тега, который содержит ссылку/изображение/ссылку, заменяет эту ссылку и возвращает все из них в списке. Эта функция может использоваться для ссылок, изображений, css-файлов, js-файлов и т. Д., И для каждого из них нужен только другой селектор, имя атрибута (и, возможно, 1-2 других переменных). Я не могу дать их в качестве аргументов этой функции, потому что каждой функции может понадобиться другое количество аргументов, а вызов casper.evaluate (site [i] ['method]) не знает о них. Он вызывает функцию без каких-либо аргументов. Вот почему я думал, что реализация функции, которая генерирует эти функции, будет самым приятным способом. Но, видимо, это не работает так, как я планировал.

Конечно, я мог бы просто скопировать эту функцию и заменить несколько переменных. Но это создало бы много избыточного кода и принесло бы все его недостатки.

Другая идея: функции вызываются с определенным количеством аргументов, которые хранятся внутри одного и того же объекта: casper.evaluate (сайт [i] ['method'], site [i] ['arg0'], site [i] ['arg1'] ...)

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

+2

Перефразируя: Вы хотите, чтобы преобразовать функцию автономной строки, встраивание ссылки на closured переменных. – SLaks

+0

Это звучит как [проблема XY] (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). – zzzzBov

+0

@zzzzBov У него наверняка есть проблема с XY. Я сталкивался с этим несколько раз и всегда находил обходное решение. Но эти обходные пути являются уродливыми (дублирование большого количества кода, что плохо для кода или кода самонастройки в контексте страницы, что снижает взаимодействие). Я тоже надеюсь, что есть чистое решение. –

ответ

0

Может быть, это может работать для вас. Это ваш пример, но позволяет выполнять функцию с любым количеством аргументов.

function foo() { 
    var func = function() { 
     //doing something with arguments of the original function: 
     return arguments; 
    }; 
    var allArgs = Array.prototype.slice.call(arguments); // 1 
    allArgs.unshift(null); // 2 
    return Function.prototype.bind.apply(func, allArgs); // 3 
} 
  1. получить все аргументы наружных видных функций и тайные их в массив
  2. поставил null в начале списка аргументов
  3. возвращение копии внутренней функции, которая связана все аргументы наружных видных функций , Нуль, который мы положили в начало массива allArgs, используется как аргумент this для функции bind.

Пример использования:

var c = foo(1,2,3,4,5,6); 
c(7); // returns: [1, 2, 3, 4, 5, 6, 7] 
0
function foo(a,b) 
{ 
    return new Function("x", "return " + a + "*x+" + b); 
} 
+0

Для 1 строковых функций, которые могут быть в порядке, но когда 20 строк кода должны быть переданы как строка, это не очень хороший способ. Но я думаю, что нет других путей? – John

Смежные вопросы