Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript:通过在数组上循环创建对象方法/属性_Javascript_Loops_Object_Methods - Fatal编程技术网

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

Javascript:通过在数组上循环创建对象方法/属性,javascript,loops,object,methods,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); }); }

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

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不是我的强项


谢谢

您的直觉是正确的,您确实可以自动执行此操作:

colors.forEach( function(color) {
    painter[color] = function(tool) {
        painter.draw(color, tool);
    };
});
这里有两件事在起作用:

  • 在JavaScript中,您可以使用点表示法和属性名称文字(
    obj.foo
    ),或使用括号表示法和属性名称字符串(
    obj[“foo”]
    )访问(获取或设置)属性。在后一种情况下,字符串可以是任何表达式的结果,包括变量查找。因此,
    painter[color]=…
    指定一个属性,该属性的名称来自
    color
    参数

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

  • 但是由于
    painter.draw
    将颜色作为第一个参数,将工具作为第二个参数,如果您愿意,还有第二种方法可以实现:您可以使用
    函数#bind
    (一种ES5功能,可以在越来越少的没有颜色的旧引擎上填充)在
    painter.draw上

    colors.forEach( function(color) {
        painter[color] = painter.draw.bind(painter, color);
    });
    
    Function#bind
    返回一个函数,该函数在调用时使用给定的
    值(
    painter
    在上面的示例中)和您提供给
    bind
    的任何其他参数调用原始函数,后跟给定给原始函数的任何参数。一个简单的例子可以让这一点更清楚:

    函数func(a,b){ snippet.log(“this.name=“+this.name”); snippet.log(“a=“+a”); snippet.log(“b=“+b”); } var o1={ 名称:“o1” }; var o2={ 名称:“o2” }; var o1boundfoo=函数绑定(o1,“foo”); var o2boundbar=函数绑定(o2,“bar”); o1boundfoo(“漂亮”);//显示: //this.name=o1 //a=foo //b=漂亮 o2boundbar(“漂亮”);//显示: //this.name=o2 //a=巴 //b=漂亮
    
    
    Wow!谢谢这不仅解决了我的问题,还解决了一些问题。你知道,我从来都不喜欢Javascript(我更喜欢像python这样的带真实类的结构化语言),但是我学的越多,我就越意识到我自己的无知,我不喜欢:)@Apollo:是的,这种情况经常发生。现在我发现,当我在一种不太灵活的语言(比如Java)中工作时,我真的很怀念JavaScript的灵活性。:-)(顺便说一句,如果您想要像JS中的类一样的东西,这里有一个我使用的助手:。它仍然是原型继承[这很好],但带有一些类的陷阱。)