构建内容不同的功能的工厂?

时间:2013-08-27 22:35:25

标签: javascript function factory

我很好奇这是否可以在JavaScript中使用。

我想要一个可以返回实际内容不同的函数的工厂函数。说这是我们的工厂:

function makeFunction(a, b, c) {
  // Implement me
  return f;
}

我希望它能像这样工作:

> makeFunction(true, true, false);
=> function() { do_a(); do_b(); }
> makeFunction(false, true, false);
=> function() { do_b(); }
> makeFunction(true, false, true);
=> function() { do_a(); do_c(); }

撇开这是否是一个好主意... 我可以这样做吗?如果是这样,makeFunction内需要发生什么?

奖励:一般来说,这种模式叫什么?


编辑:我应该澄清我 寻找的东西:使用闭包的理智方法。例如。以下具有正确的效果,但不会更改功能内容/正文:

function makeFunction(a, b, c) {
  return function() {
    if (a) { do_a(); }
    if (b) { do_b(); }
    if (c) { do_c(); }
  }
}

5 个答案:

答案 0 :(得分:1)

此解决方案为您完成所有工作,使用其名称在func数组中定义所需的函数,然后使用它来创建。

function a (){
    console.log("a");
};
function b() {
    console.log("b");
};
function c() {
    console.log("c");
};
function makeFunction() {
    var funcs = [a, b, c];
    var finalfunc = [];
    for (var i = 0; i < arguments.length && i < funcs.length; i++) {
        if (arguments[i]) {
            finalfunc.push(funcs[i]);
        }
    }
    return function () {
        var f = finalfunc;
        for (var a = 0; a < f.length; a++) {
            f[a]();
        }
    };
};

示例:

var z = makeFunction(true);
z();//outputs a

var z = makeFunction(true, false, true);
z();//outputs a c

var z = makeFunction(true, true, false);
z();//outputs a b

var z = makeFunction(true, true, true);
z();//outputs a b c

var z = makeFunction(true, true, true, true);
z();//outputs a b c

修改

在我写完之前我没看到你不想要关闭,但无论如何我都会把它留在这里

虽然您已经说过,但这可能是一种更安全的方式。它还直接回答了排除这个事实的问题,我创建了一个只包含你想要在其中运行的函数的函数。每个函数都没有if语句,它只取决于你提供的函数和参数:)

它也是完全动态的,并不依赖于为每个函数定义条件。

答案 1 :(得分:1)

是的,这是可能的。不,我不打算评论这种方法的(感知)价值。

以下是一个快速示例:

window.addEventListener('load', mInit, false);

function createFunction(funcName, message)
{
    var script = document.createElement('script');
    var scriptContents = 'function ' + funcName + '()\n';
    scriptContents += '{\n\talert("' + message + '");\n}\n';
    script.appendChild( newTxt(scriptContents) );
    document.head.appendChild(script);
}

function mInit()
{
    createFunction('myFunc', 'hello world');
    myFunc();
}

<强>输出:

<script>function myFunc()
{
    alert("hello world");
}
</script>

我不确定该功能是否会立即起作用,因此测试如上所示。 (它确实如此)

过去我有一个想法,就是将脚本隐藏在图像的alpha通道中......

答案 2 :(得分:1)

您可以使用Function构造函数来完成此任务。例如:

// Globals can be seen by the function we're going to create.
function do_a() { /* stuff */ }
function do_b() { /* stuff */ }
function do_c() { /* stuff */ }

function makeFunction(a, b, c) {
  var contents = [];
  if (a) { contents.push("do_a();"); }
  if (b) { contents.push("do_b();"); }
  if (c) { contents.push("do_c();"); }
  return new Function(contents.join(''));
}

console.log(makeFunction(true, true));
console.log(makeFunction(true, false, false));
console.log(makeFunction(false, true, true));

以上代码将以下内容打印到控制台:

function anonymous() {
  do_a();do_b();
}
function anonymous() {
  do_a();
}
function anonymous() {
  do_b();do_c();
}

我相信这符合问题的要求。一些JavaScript库实际上使用这种技术在运行时根据程序的需要编译非常有效的函数。但是,这种方法有一些值得注意的缺点:

  • 使用Function构造函数创建的函数仅继承全局范围。根据您的代码需要做什么,这可能是一个交易破坏者。
  • 这种方式的函数构造很慢,因为引擎必须将函数源转换为可执行代码。 (注意:这并不意味着创建的函数本身会很慢。实际上,它们会正常运行。)
  • 很难写出这样的功能。 (引用/ unquoting。)
  • 功能内容不会是lint-able。

答案 3 :(得分:0)

以下“手动”方法可以完成工作,但仅在您需要处理一些条件和/或您喜欢打字时才建议使用。

function makeFunction(a, b, c) {
   if (a && b && c) {
      return function() { do_a(); do_b(); do_c(); }
   }

   if (a && b && !c) {
      return function() { do_a(); do_b(); }
   }

   // You get the idea...
}

优点:有效吗? 缺点:如果您需要提供大量排列......祝您好运:)

答案 4 :(得分:0)

您可以使用对象并返回它的方法。

我真的没有看到这一点。

function makeFunction(a, b) {
 var f = {
    a:function(){console.log("IcanBeANythign")},
    b:function(a,b){return a+b}
  };
  if(a){
  return f.a;
  }
  if(b){
  return f.b;
  }
}
var f = makeFunction(false,true)(3,4) // 7

类似的东西是currying或更准确的部分应用。 已经非常彻底地回答了here

您可以这样做:

function curryPlus(a){
          return function(b){
          return a+b;
          }
    }

var add1 = curryPlus(1);
add1(2) // Outputs: 3