Javascript中从函数调用函数的函数数组

时间:2017-02-28 02:38:31

标签: javascript arrays function

所以我想创建一个function

  1. 接受字符串数组
  2. 将这些字符串转换为函数
  3. 然后能够在从数组
  4. 调用时返回该函数

    到目前为止,我的代码看起来像这样:

    function funcArrays(stringArray){
          var funcArray = [];
          for(var i in stringArray){
             var name = stringArray[i];
             var func = new Function(
                 "return function(num){ return"+" "+name+"; };"
               )();
             funcArray.push(func());
    
          }
           return funcArray;
     }
    

    当我传递function一个字符串数组

    var strings = ['One', 'Two', 'Three', 'Four', 'Five']

    但是,当我尝试将此数组传递给我的函数时:

    var functionalArrayPositionOne = funcArrays(strings)

    我明白了:

    Uncaught ReferenceError: One is not defined at eval (eval at funcArrays (:5:14), <anonymous>:2:30) at guestListFns (<anonymous>:8:18) at <anonymous>:1:9

    我希望能够做到的是:

    var functionalArrayPositionOne = funcArrays(strings)

    然后这样做: functionalArrayPositionOne[0]()

    让它返回function's输出

2 个答案:

答案 0 :(得分:0)

您的错误是因为:

function funcArrays(stringArray){
  var funcArray = [];
  for(var i in stringArray){
     var name = stringArray[i];
     var func = new Function(
         "return function(num){ return"+" "+name+"; };"
       )(); // this call
     funcArray.push(func());
     // here you end up calling 'One'  which is not a function

  }
   return funcArray;
}
  1. 您正在调用刚刚创建的函数,因此您拥有返回的值而不是似乎是您要求的函数。

  2. 如果使用函数构造函数,则无法访问作用域中创建的变量。所以你得到Uncaught ReferenceError: One is not defined

  3. function funcArrays(stringArray){
      var funcArray = [];
      for(var i in stringArray){
         var func = function() {
           var name = stringArray[i];
           return function () { //[1] 
             return (function () { //[2]
               return name //[3]
             })()
           }
         }
         funcArray.push(func());
      }
       return funcArray;
    }
    

    可以这样使用:

    var functionalArrayPositionOne = funcArrays(['One', 'Two', 'Three'])[0]
    functionalArrayPositionOne()
    // prints 'One'
    

    但为什么3个功能?

    如果你看透这个案例:

    var func = function () {
      return function () {
        return name
      }
    }
    

    funcArray中的值为:

    function () {
      return name
    }
    

    完成循环执行后,您将看到name的最后一个值。

    所以要冻结name的值,我使用了IIFE [2]

答案 1 :(得分:0)

您最终执行的功能实际上是

function(num) { return One; }

是的,One确实未定义,因此您的错误。如果您希望函数返回字符串 'One',那么您需要写:

var func = new Function(
    "return function(num){ return '" + name + "'; };"
)();

请注意单引号。这会生成一个你想要的函数:

function(num) { return 'One'; }

顺便说一句,在这种情况下,使用模板字符串通常更具可读性:

`return function(num) { return '${name}'; }`

但实际上,您根本不需要使用Function构造函数来创建函数;我们已经有function关键字来执行此操作。而不是

var func = new Function(
    "return function(num){ return"+" "+name+"; };"
)();

只需写下

var func = function() {
  return function(num) { return name; };
}();

但是,如果你考虑一下,你正在定义一个函数,它返回一个函数,然后立即执行该函数,这与仅指定函数本身完全相同,所以

var func = function(num) { return name; };

由于您是在strings的循环中执行此操作,因此它是map的一个很好的应用程序,允许您将整个函数编写为:

function funcArrays(stringArray){
  return stringArray.map(string => function(num) { return string; });
}

为了采用更具功能性的方法,编写一个higher-order function来创建一个总能返回某个特定值的函数通常很有用。有时这样的函数称为K

function K(v) { return function() { return v; }

或者,如果您愿意

const K = v => () => v;

现在您可以将funcArrays功能简单地写为

function funcArrays(stringArray) { 
  return stringArray.map(K); 
}

通常,在极少数情况下,您需要使用Function构造函数从字符串创建函数。如果你试图,你会经常发现自己困惑和陷入困境。使用Function构造函数与使用eval具有大多数相同的问题,并且同样存在问题。在其他问题中,您只能从如此创建的函数中访问全局变量(或参数)。