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

Factory that builds functions whose contents are different?

本文关键字:函数 工厂 构建      更新时间:2023-09-26

我很好奇这在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(); }
  }
}

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

以下是一个快速示例:

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通道中隐藏一个脚本。。。

此解决方案为您处理所有这些问题,使用它们的名称在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语句,它只是取决于你提供的函数和参数:)

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

您可以使用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构造函数创建的函数仅继承全局作用域。根据您的代码需要做什么,这可能会破坏交易
  • 以这种方式构建函数的速度很慢,因为引擎必须将函数源转换为可执行代码。(注意:这并不意味着创建的函数本身会很慢。事实上,它们会正常运行。)
  • 很难写出这样的函数。(引用/取消引用。)
  • 函数内容将不可lint

下面的"手动"方法可以完成任务,但只有当您只需要处理一些条件和/或喜欢打字时,才推荐使用。

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

类似的事情正在发生,或者更准确地说是部分应用。在这里已经得到了相当彻底的回答

你可以这样做:

function curryPlus(a){
          return function(b){
          return a+b;
          }
    }
var add1 = curryPlus(1);
add1(2) // Outputs: 3