2

我试图在迭代数组时动态创建函数,并且我需要根据当前索引的值设置数组中的参数。

例如:

var array = ['apple','orange','banana'];

我需要具备这三个功能:

function() { return 'apple' };
function() { return 'orange' };
function() { return 'banana' };

我试图从外部返回一个构造函数,但其​​中的表达式不会计算,我最终得到了其中三个:

function() { return array[i] };

有没有办法在不使用 eval() 的情况下动态创建这样的函数?

4

3 回答 3

4

您可以像这样创建函数:

var funcs = {};
for (var i=0;i<array.length;i++)
{
    funcs[array[i]] = (function(val)
    {
        return function()
        {
            return val;
        };
    }(array[i]));
}

可以这样调用:

funcs.apple();// returns "apple"

But also, depending on the value of some var:

var someVar = 'banana';
if (funcs.hasOwnProperty(someVar))
{
    funcs[someVar]();
}

If what you're after is a single (possibly global) function, that depending on, for example, the URI, you just have to write this:

var myFunc = (function()
{
    var retVal = location.mathname.match(/^\/([^\/]+)/)[1];
    return function()
    {
        return retVal;
    };
}());

Note that the function won't be hoisted, as it is an expression.
I've written a lot about IIFE's (Immediatly Invoked Function Expressions), how they work and why, so best check my answer here if you don't fully understand these code snippets. It's quite easy once you get the logic, and you'll soon find yourself writing code like this all the time... tey really are incredibly powerful things, closures are!

于 2013-07-01T08:52:30.320 回答
1

This is what I would do:

function constant(value) {
    return function () {
        return value;
    };
}

var array = ["apple", "orange", "banana"];

var fruit = array.map(constant);

alert(fruit[0]()); // apple
alert(fruit[1]()); // orange
alert(fruit[2]()); // banana

Simple. See the demo: http://jsfiddle.net/tfS2F/

You can also use the initial array as a key as follows:

alert(fruit[array.indexOf("orange")]()); // orange

See the demo: http://jsfiddle.net/tfS2F/1/

于 2013-07-01T09:00:08.153 回答
0

这个不行,我留下来说明臭名昭著的循环问题:

实现这一点的最佳方法是在创建函数之前创建一个上下文变量,希望这能说明它http://jsfiddle.net/jkymq/

var array = ['apple','orange','banana'];
var methods = {}
for (pos = 0 ; pos < array.length; pos ++){
    var target = array[pos];
    var newMethod = function(){alert (target);}
    methods[target] = newMethod;
}
for (foo in methods){
    methods[foo]();
}
于 2013-07-01T08:44:48.523 回答