我正在创建一种位于javascript中的dsl,并且要使其尽可能干净,重要的是我不必专门将其传递给它,它可以将它们捡起来在当前范围内按名称命名-但我想知道是否确实可行。如果我在使用函数,是否可以通过调用程序函数访问局部变量?
我知道您不应该能够做到这一点,但是它全都在堆栈中,调试器可以做到,而且似乎没有很多对您可以在javascript中进行的操作的限制,因此,我想知道是否存在某种晦涩的方法,即使该方法很容易破解。
例如
function dsl( someString )
{
// can I access bob and cindy here?
}
function someRealFunction()
{
var bob = [1,2,3,4];
var cindy = [1,2,3,8];
return dsl("difference bob and cindy");
}
这与将范围传递给另一个函数的问题稍有不同,因为我不想传递范围-我只想隐式地选择那里的范围。调试器可以做到,因此从根本上说信息实际上就在那儿-问题是是否可以访问它。
答案 0 :(得分:1)
晦涩的方式-你说;
function dsl( someString )
{
// can I access bob and cindy here?
eBob=arguments.callee.caller.toString().split("\n")[2];
eCindy=arguments.callee.caller.toString().split("\n")[3];
eval(eBob);
eval(eCindy);
console.log(arguments.callee.caller)
console.log("bob", bob);
console.log("cindy", cindy);
}
function someRealFunction()
{
var bob = [1,2,3,4];
var cindy = [1,2,3,8];
return dsl("difference bob and cindy");
}
someRealFunction();
仅出于理论推理和安全考虑。显然,不要在类似于生产代码的地方使用它。
答案 1 :(得分:1)
回调/关闭模式可能会满足您的要求:
function dsl( someString, cb )
{
// can I access bob and cindy here?
cb();
}
function someRealFunction()
{
var bob = [1,2,3,4];
var cindy = [1,2,3,8];
return dsl("difference bob and cindy", cb);
function cb() {
console.log(diff(bob, cindy));
}
}
答案 2 :(得分:0)
免责声明:当然,这里的正确方法是更改范例以匹配您使用的语言,并使用@torazaburo建议的回调模式或@Mark M建议的副本中的解决方案。 / p>
但是,由于您专门要求“某种晦涩的方法,即使它是非常hacky”,因此这里是晦涩的hacky方法二。将其作为单独的答案发布是另一种方法。
您可以使用获取名称的评估值的getter扩展字符串类。您需要在调用函数中创建原型,否则getter的作用域将不正确。
function dsl( someString )
{
// can I access bob and cindy here?
console.log(someString.handKeysToKingdom("cindy"));
console.log(someString.handKeysToKingdom("bob"));
}
function someRealFunction()
{
String.prototype.handKeysToKingdom=function(name){return(eval(name))};
var bob = [1,2,3,4];
var cindy = [1,2,3,8];
return dsl("difference bob and cindy");
}
someRealFunction();
我认为大多数JS开发人员都会同意的一种显而易见的非hacky方式看起来很干净。
function dsl( someString, params )
{
// can I access bob and cindy here?
console.log(params['bob']);
console.log(params.cindy);
return
}
function someRealFunction()
{
var dslParams={};
dslParams.bob= [1,2,3,4];
dslParams.cindy = [1,2,3,8];
return dsl("difference bob and cindy",dslParams);
}
someRealFunction();
使用类似的逻辑,您可以在某种程度上低调地滥用函数是对象的事实,并通过在dsl对象上设置参数来传递参数。
function dsl( someString )
{
// can I access bob and cindy here?
console.log(dsl['bob']);
console.log(dsl.cindy);
return
}
function someRealFunction()
{
dsl.bob= [1,2,3,4];
dsl.cindy = [1,2,3,8];
return dsl("difference bob and cindy");
}
someRealFunction();