的Javascript:通过遍历数组
什么我真的很为创建对象的方法/属性是类似下面的代码:的Javascript:通过遍历数组
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
参数在那里。更多关于关闭(在我的博客):Closures are not complicated
但由于painter.draw
需要的颜色作为第一个参数和工具作为其第二个,还有,如果你愿意,你可以做到这一点,虽然第二个办法:你可以“curry”的颜色参数为使用Function#bind
方法(一ES5功能,可以在越来越小数量的旧引擎来垫高没有它)对painter.draw
:
colors.forEach(function(color) {
painter[color] = painter.draw.bind(painter, color);
});
Function#bind
返回功能当被调用时,用给定的调用原始函数值(painter
在上面的例子)和你提供给bind
任何进一步的参数,随后给予原始任何参数。一个简单的例子可能会做出更加清晰:
function func(a, b) {
snippet.log("this.name = " + this.name);
snippet.log("a = " + a);
snippet.log("b = " + b);
}
var o1 = {
name: "o1"
};
var o2 = {
name: "o2"
};
var o1boundfoo = func.bind(o1, "foo");
var o2boundbar = func.bind(o2, "bar");
o1boundfoo("nifty"); // Shows:
// this.name = o1
// a = foo
// b = nifty
o2boundbar("nifty"); // Shows:
// this.name = o2
// a = bar
// b = nifty
<!-- Temporary snippet object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
哇!谢谢。这不仅解决了我的问题,而且解决了一些问题。你知道,我从来没有喜欢过Javascript(我喜欢像真正类的python这样的更多结构化语言),但是我学得越多,我越认识到我自己的无知,我不喜欢:) – Apollo 2014-11-05 17:49:10
@Apollo:是的,发生了这样的事情许多。现在我发现,当我用一种不太灵活的语言(Java说)工作时,我真的错过了* JavaScript的灵活性。 :-)(顺便说一下,如果你想要的东西就像JS中的类一样,下面是我使用的帮助器:http://code.google.com/p/lineagejs/。它仍然是原型继承[这很棒],但是带有一些课堂的特征。) – 2014-11-05 18:06:07