【问题标题】:How to create dynamic object members that are able to reference enclosed variables/functions?如何创建能够引用封闭变量/函数的动态对象成员?
【发布时间】:2014-09-01 03:47:21
【问题描述】:

我将如何创建一个动态对象,将其包装在一个闭包中,然后再将成员添加到能够引用封闭变量的对象中?

如本例所示,test.myFunct() 不能引用封闭的example 变量:

var example = "from global";
(function (global) {
    var example = "from closure";
    global.test = {};
}(this));

test.myFunct = fnction () { return example; };
test.myFunct(); // "from global"

所以我尝试创建一个加法器函数,希望能解决问题,但无济于事:

var example = "from global";
(function (global) {
    var example = "from closure";
    global.test = {
        add: function (name, value) { global.mJSON[name] = value; }
    }
}(this));

test.add("myFunct", function () { return example; });
test.myFunct(); // "from global"

有没有办法在运行时后期动态地向对象添加成员,以引用封闭的成员?

为什么需要它

我正在使用mIRC's COM 实现来访问MSScriptControl.ScriptControl 的jScript 引擎。由于使用 mIRC 的限制,我被限制为从 mIRC 执行的每个命令约 4k 字节。因此,在调用ScriptControlAddCodeExecuteStatementEval 方法之前,我需要将我的JS 文件分解为大约3500 字节或更小的块。

注意事项

我宁愿不必使用返回所附变量/函数值的静态“帮助”函数。

【问题讨论】:

  • 当您想让任意函数访问它们时,为什么要尝试将它们封装在闭包中,而不是简单地将它们设为公共属性?
  • 我的计划是/是有一个包装函数,它消化参数,然后根据这些消化的参数返回一个动态对象。
  • 你会如何使用它?你在哪里需要这个?
  • 我正在使用mIRC's COM 实现来访问 MSScriptControl.ScriptControl 的 jscript 引擎。由于使用 mIRC 的限制,我被限制为从 mIRC 执行的每个命令约 4k 字节。因此,在调用 ScriptControl 的 AddCode、ExecuteStatement 或 Eval 方法之前,我需要将我的 js 文件分解为大约 3500 字节或更小的块。
  • 天哪。所以你对黑魔法没问题?

标签: javascript com closures msscriptcontrol


【解决方案1】:

有没有一种方法可以在运行时稍后将成员动态添加到可以引用封闭成员的对象中?

No1,这与 (javascript) 闭包的定义相矛盾。只需使用公共属性而不是封闭变量。


1:您可以使用eval 在闭包范围内(从字符串)创建一个新函数并将其作为成员。但这纯粹是邪恶的:

var example = "from global";
(function (exports) {
    var example = "from closure";
    exports.addPrivileged = function(name, args, body) {
        body = arguments[arguments.length-1];
        args = Array.prototype.slice.call(arguments, 1, -1).join(", ");
        this[name] = eval("(function("+args+"){"+body+"})");
        name = args = body = null;
    };
}(test={}));

test.addPrivileged("myFunct", "return example");
console.log(test.myFunct()); // "from closure"

【讨论】:

  • 几点说明:'export'是保留字,会引发错误,test.add(...)应该是test.addPrivileged(...)
  • @SReject:当然。我在尝试时已经修复了这些,但忘记将其复制回帖子中。
猜你喜欢
  • 1970-01-01
  • 2020-08-09
  • 1970-01-01
  • 2012-05-18
  • 1970-01-01
  • 2016-10-04
  • 1970-01-01
  • 2012-12-20
  • 1970-01-01
相关资源
最近更新 更多