Se entendi sua pergunta corretamente, você está procurando por escopo dinâmico . Javascript tem escopo lexical, então para capturar uma variável, o fechamento deve estar textualmente dentro de seu escopo. Caso contrário, isso não é possível, sem contar truques mais ou menos bobos como, por exemplo:
function makeClosure(context) {
return function() {
return context("a") + 1;
};
}
function y(evalThis) {
var a = 2;
if(evalThis)
return eval(evalThis);
return makeClosure(y);
}
closure = y();
document.write(closure()) // 3
Veja também É possível obter escopo dinâmico em JavaScript sem recorrer a eval? para mais discussão e exemplos.
Quanto à sua pergunta do MongoDB especificamente, não é possível em javascript puro injetar uma variável no escopo de alguma função (novamente, sem recorrer a eval). Mas o map-reduce do Mongo é escrito em C++, não em JS, e pode manipular o escopo de maneiras arbitrárias:
_scope->setFunction("emit", etc
Consulte a fonte .
Para completar, aqui está um exemplo com
eval
:function map(ary, fun) {
// define some locals
var LOCAL = 42;
// re-evaluate the function within the scope
eval("fun=" + fun);
// now fun sees our locals
return ary.map(fun);
}
document.write(
map([1,2,3], function(x) { return x * LOCAL }) // [ 42, 84, 126 ]
)