我真的不确定你的目标是什么,但如果你被允许摆脱theConfig
(使用它的版本不是window.theConfig
)等等,那么你可以使用 IIFE。
var funcs = {
loadConfiguration : (function () {
var theConfig = {};
//or, if you prefer...
theConfig = some.object.somewhere.else.config;
return function () {
// this now resolves to the `theConfig` which is in the closure
// created by the IIFE
theConfig.one = true;
};
}());
};
您甚至可以使用该 IIFE 传递theConfig
. 这里要注意的重要一点是,theConfig
在这些 IIFE 运行之前必须存在
loadConfiguration : (function (theConfig) {
return function () { theConfig.x = 3; };
}(newConfigObject))
如果这些都不是您想要的,那么请更具体地说明您想从中获得什么。
编辑
根据你的更新,我有一个可怕的想法,理论上可行。
它很丑,很像忍者,而且我不一定会在我的最终产品中加入它。
也就是说,它应该是可以预测的,*只要您要替换的功能不需要访问闭包* -this
可以使用 call 或 apply 来破解,但如果该功能试图访问其他东西是一个全局的(或者更糟的是,在闭包中定义,虽然它看起来不像),那么 THOSE 也需要被导入。
看看: // 你的“loadConfig”当前所在的地方 var codeblock = { // 我们想要交换 target_func 值的函数: function () { theVar.prop = 1; theVar.attr = 2; } }; // 我们要使用的新配置对象 var alternate = { config : {} };
// this whole thing would get injected somewhere into the page
// put it where you're about to fire your stuff
(function () {
// the name of the variable doesn't actually matter right here
// but I'm doing it for consistency
var theVar = alternate.config,
// grabbing the function as a string
string = codeblock.target_func.toString(),
// using regex to remove the `"function anonymous() {" + "}"` wrapper
bare_func = string.replace(/^function[^{]+{/, "")
.replace(/}$/,""),
// using the new Function constructor to pass in "theVar" (where the name matters)
// the constructor doesn't accept closures, but any function that is created inside of the constructor does
// so we return a new function (with the exact contents of the original function
// but now, `theVar` is a parameter we're passing in
new_func = new Function ("theVar", "return function () {" + bare_func + "};"),
// this is the new function returned from the constructor, and we're passing in "theVar"
// again, name on the outside doesn't matter -- name in the `new Function` constructor DOES
enclosed = new_func(theVar);
// putting the function back where we stole it from
codeblock.target_func = enclosed;
}());
如果我们codeblock.target_func();
之前跑过,它会设置
window.theVar.prop = 1;
window.theVar.attr = 2;
...但是如果我们现在调用该函数...
codeblock.target_func();
alternate.config.prop; // 1
alternate.config.attr; // 2