Javascript 构建内容不同的函数的工厂?

Javascript 构建内容不同的函数的工厂?,javascript,function,factory,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);

我很好奇这在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(); }
function curryPlus(a){
          return function(b){
          return a+b;
          }
    }

var add1 = curryPlus(1);
add1(2) // Outputs: 3
不管这是不是个好主意我可以这样做吗?如果是这样,在
makeFunction
内部需要做什么?

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


编辑:我应该澄清一些我不想要的东西:使用闭包的合理方法。例如,以下内容具有正确的效果,但不会改变功能内容/主体:

function makeFunction(a, b, c) {
  return function() {
    if (a) { do_a(); }
    if (b) { do_b(); }
    if (c) { do_c(); }
  }
}
以下“手动”方法可以完成工作,但仅当您只需要处理一些条件和/或喜欢打字时,才推荐使用

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...
}
优点:有效吗缺点:如果您需要提供大量排列。。。祝你好运:)

以下“手动”方法可以完成工作,但仅当你只需要处理一些情况和/或喜欢打字时才建议使用

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...
}

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

你可以使用一个对象并返回它的方法

但我真的不认为这有什么意义

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
类似的东西是咖喱或更准确地说是部分应用。 它已经得到了相当彻底的回答

您可以这样做:

> 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(); }
function curryPlus(a){
          return function(b){
          return a+b;
          }
    }

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

可以使用对象并返回其方法

但我真的不认为这有什么意义

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
类似的东西是咖喱或更准确地说是部分应用。 它已经得到了相当彻底的回答

您可以这样做:

> 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(); }
function curryPlus(a){
          return function(b){
          return a+b;
          }
    }

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

此解决方案为您解决了所有问题,使用函数名在
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]();
        }
    };
};
编辑

直到我写完它,我才知道你不想要闭包,但无论如何我会把它保存在这里

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


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

此解决方案为您解决所有问题,使用函数名在
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]();
        }
    };
};
编辑

直到我写完它,我才知道你不想要闭包,但无论如何我会把它保存在这里

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


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

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

下面是一个快速示例:

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>
函数myFunc()
{
警报(“你好世界”);
}
我不确定该函数是否能立即工作,因此进行了如上所示的测试。(顺便说一句,确实如此)


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

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

下面是一个快速示例:

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>
函数myFunc()
{
警报(“你好世界”);
}
我不确定该函数是否能立即工作,因此进行了如上所示的测试。(顺便说一句,确实如此)


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

您可以使用
函数
构造函数来实现这一点。例如:

// 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库实际上使用这种技术在运行时根据程序的需要编译非常高效的函数。然而,这种方法有几个明显的缺点:

  • 使用
    函数
    构造函数创建的函数只继承全局范围。根据您的代码需要做什么,这可能会破坏交易
  • 以这种方式构造函数很慢,因为引擎必须将函数源转换为可执行代码。(注意:这并不意味着创建的函数本身会很慢。事实上,它们会正常运行。)
  • 很难编写这样的函数。(引用/取消引用)
  • 函数内容将不可忽略

您可以使用
函数
构造函数来完成此操作。例如:

// 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库实际上使用这种技术在运行时根据程序的需要编译非常高效的函数。然而,这种方法有几个明显的缺点:

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