【问题标题】:How to write simple, extensible, modular Javascript如何编写简单、可扩展、模块化的 Javascript
【发布时间】:2013-06-25 15:10:06
【问题描述】:

我需要一种机制,人们可以使用他们自己的模块扩展我的基本代码 - 但我正在努力想出一个简单的机制来做到这一点。

示例:用户可以扩展的名为“test”的函数。每个用户模块都在原始模块之后加载 - 因此每个用户模块都需要在最后一个模块上构建(它们的加载顺序无关紧要,或者可以通过命名来控制)

我开始玩这样的东西

var test = function() { // the master function
    console.log("1");
}

var ltest = test; // module 1
var test = function() {
    ltest();
    console.log("2");
}

var ltest2 = test; // module 2
var test = function() {
    ltest2();
    console.log("3");
}

然后,当 'test' 被调用时,它将运行每个人的代码(假设没有人忘记他们的回调!!)

这可行,但它依赖于每个模块声明它自己的唯一“回调”变量(ltest,ltest2) - 如果有人使用相同的变量,我们将得到一个“超出调用堆栈”,因为这些变量是全局变量范围...

谁能建议一个更聪明/更好的系统 - 或者指出一些相同的例子?

有很多关于继承的材料,但我不想创建新的东西来扩展旧的东西——我只想扩展旧的东西!!

附言从模块模式中获取匿名函数的东西 - 我得到了这个

var test = function() {
    console.log("1");
}

(function() {
    var oldtest = test;
    test = function() {
        oldtest();
        console.log("2");
    }
}())

(function() {
    var oldtest = test;
    test = function() {
        oldtest();
        console.log("3");
    }
}())

这可能是我的问题最简单的解决方案 - 但不一定是最好的系统(因为它取决于作者记得回调代码 - 一个狡猾的模块会破坏一切)

【问题讨论】:

标签: javascript design-patterns extensibility modular-design


【解决方案1】:

Module Pattern 是您所需要的。

尤其是“增强”或“松散增强”模式:

var MODULE = (function (my) {
    var old_moduleMethod = my.moduleMethod;

    my.moduleMethod = function () {
        // method override, has access to old through old_moduleMethod...
    };

    return my;
}(MODULE || {}));

【讨论】:

  • 这也很有趣 - 如果没有别的,我对变量范围和匿名函数的理解在过去 20 分钟内爆炸了!!
  • 我采用了模式使用匿名函数来封装值的方式,并用它更新了第一个问题(因为代码在 cmets 中显示效果不佳)
【解决方案2】:

你可以做一个这样的函数

function extendFunction(fn, pre, post) {
    return function () {
        var arg = arguments;
        if (pre) arg = pre.apply(this, arg);   // call pre with arguments
        arg = fn.apply(this, arg);             // call fn with return of pre
        if (post) arg = post.apply(this, arg); // call post with return of fn
        return arg;
    };
}

然后扩展如下

var test = function () { // the master function
    console.log("1");
};
test = extendFunction(
    test, // function to extend
    null, // thing to do first
    function() {console.log("2");} // thing to do after
);
test = extendFunction(
    test,
    null,
    function() {console.log("3");}
);
test(); // 1, 2, 3

这与“扩展”的正常含义非常不同,您可以为 Objects 或设置 prototype 链和“模块”提供新属性通常涉及将所有代码包装在 函数表达式 中,以免污染命名空间。

【讨论】:

  • 这很有趣——所有这些函数都是异步事件链/瀑布的一部分(与从 NOSQL 数据库存储或检索内容有关)——所以我认为这种方法非常有效。 .
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-17
  • 2012-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-10
相关资源
最近更新 更多