我对此做了一些研究,我不太希望这是可能的,但也许你们中间有一个JS向导知道如何解决这个问题。
我有一个像这样的JS函数:
{
loadConfiguration: function(){
theConfig.oneConfigOption = true;
theConfig.anotherConfigOption = false;
}
}
这是旧软件部分中的一种界面。截至目前,theConfig
一直是全局变量。由于我不喜欢全局变量,我想从函数外部定义theConfig
对象。
问题是,出于向后兼容性原因,函数的签名必须始终保持function()
,并且需要设置对象的引用必须始终命名为theConfig
,以便上述代码仍然是有效的配置加载器。 实际上我无法更改此代码块所在文件中的任何内容。
我可以改变的唯一地方是调用函数的位置(因为它在另一个文件中调用,可以从一个版本更新到另一个版本:
loadConfiguration();
我可以在这里做任何事情..封装函数,闭包或类似的东西。所以我的问题是,您能想出一种方法来强制theConfig
loadConfiguration
的引用指向我在调用函数时定义的对象而不用更改其签名吗?
答案 0 :(得分:0)
我真的不确定你的目标是什么,但如果你被允许摆脱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 RUN之前存在
loadConfiguration : (function (theConfig) {
return function () { theConfig.x = 3; };
}(newConfigObject))
如果这些都不是您想要的,那么请更加具体地说明您希望从中得到什么。
根据你的更新,我有一个可怕的,可怕的想法,理论上有效
这很难看,它是忍者,而且这不是我必须放在最终产品中的东西。
也就是说,它应该是非常可预测的, *尽管你需要更换的功能不需要访问关闭* - this
可以通过电话或申请被黑客攻击,但是如果函数试图访问其他全局的东西(或者更糟糕的是,在闭包中定义,虽然它看起来不像),那么也需要导入。
看看: //你的“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