Javascript:通过循环数组创建对象方法/属性

时间:2014-11-05 14:54:54

标签: javascript loops object methods

我真正想要的是如下代码:

var painter = {}; // An object to hold methods
var colors = ['blue', 'red', 'green', 'yellow']; // The names of methods to be defined
colors.forEach( function(color) {
    painter.defineMethod(color, function(){ console.log(color); });
});

painter.blue() // writes blue
painter.red() // writes red
etc.

painter.defineMethod()是关键。

我必须为一个对象定义几个(超过40个)方法,它们基本上都是相同的,具有微小但可预测的更改,它们实际上都调用另一个方法。例如:

painter.blue = function(tool) {
   painter.draw('blue', tool); // Would paint blue with a brush or pencil or whatever.
}

这样的事情是否可能,或者我是否明确地定义了所有这些属性?这种或那种方式有任何性能上的好处吗?

在Javascript中,具有变量变量或魔术方法的语言很容易被证明是困难的(或不可能的)。虽然我承认javascript不是我的强项。

谢谢!

1 个答案:

答案 0 :(得分:2)

你的直觉是正确的,你确实可以实现自动化:

colors.forEach( function(color) {
    painter[color] = function(tool) {
        painter.draw(color, tool);
    };
});

这里有两件事情可以解决:

  1. 在JavaScript中,您可以使用点表示法和属性名称​​ literal obj.foo)或使用括号表示法来访问(获取或设置)属性属性名称​​ string obj["foo"])。在后一种情况下,字符串可以是任何表达式的结果,包括变量查找。因此painter[color] = ...会分配给名称来自color参数的属性。

  2. 然后我们使用这样一个事实,即我们创建的函数是对我们给forEach的迭代函数的调用的闭包,因此我们可以使用{{ 1}}该函数中的参数。即使对迭代函数的调用返回,因为我们在调用中创建了一个函数并保留了对它的引用,该函数保留了对上下文的引用(它在上下文中是 em ),所以我们可以依赖color论证。关于闭包的更多信息(在我的博客上):Closures are not complicated

  3. 但是,由于color将颜色作为第一个参数而工具作为第二个参数,因此,如果您愿意,可以采用第二种方式:您可以" {{3 }}" painter.draw上使用Function#bind(一种可以在越来越少的旧引擎上填充的ES5功能)上填充方法的颜色参数:

    painter.draw

    colors.forEach( function(color) { painter[color] = painter.draw.bind(painter, color); }); 返回一个函数,该函数在调用时调用具有给定Function#bind值(上例中的this)的原始函数以及您提供给{{1的任何其他参数然后是给原始的任何参数。一个简单的例子可能会更清楚:

    
    
    painter
    
    bind