我发现自己越来越多地编写以下JavaScript,我想知道这是否是一种常见的模式,如果是这样,它叫什么?
部分代码和模式:
var fruits = ["pear", "apple", "banana"];
var getNextFruit = function() {
var _index = 0,
_numberOfFruits = fruits.length;
getNextFruit = function() {
render(fruits[_index]);
_index = (_index + 1) % _numberOfFruits;
}
getNextFruit();
};
我有一个不带参数的函数,在函数内部我重新定义函数并立即调用它。在函数式语言中,这可能是一个返回的函数,JavaScript只是让它更容易,因为你可以重用函数的名称。因此,您无需更改实施即可扩展功能。
我还可以想象这个模式对于你的"缓存"的记忆非常有用。是我们环绕的状态。
我甚至有时会在函数中使用get
或set
方法实现此操作,如果它有意义,我可以获取状态。添加的小提琴就是一个例子。
因为这是一个主要面向JavaScript的问题:The obligatory fiddle
答案 0 :(得分:2)
我有一个不带参数的函数,在函数内部我重新定义函数并立即调用它。 这是一个有效的模式,它叫什么?
重新定义自身的函数通常是反模式,因为它会使事情复杂化。是的,交换整个函数有时比在函数中放置if (alreadyInitialised)
条件更有效,但它很少值得。当您需要优化性能时,您可以尝试对两种方法进行基准测试,但另外建议尽可能保持简单。
模式“在第一次调用时初始化”对于纯计算(在函数式编程中)被称为laziness,对于对象(在OOP中)被称为singleton。
然而,大多数时候没有理由推迟对象/功能/模块的初始化,直到第一次使用它为止。为它采取的资源(包括时间和记忆)都是微不足道的,特别是当你确定在程序中至少需要它一次时。为此,请在JavaScript中使用IIFE,在创建对象时也称为module pattern。
答案 1 :(得分:1)
通过闭包创建函数是JavaScript中非常常见的模式。我个人会这样做:
var fruits = ["pear", "apple", "banana"];
var getNextFruit = function(fruits) {
var index = 0,
numberOfFruits = fruits.length;
function getNextFruit() {
render(fruits[_index]);
index = (_index + 1) % numberOfFruits;
}
return getNextFruit;
}(fruits);
没有充分理由(在我看来)将变量名称与前导下划线混为一谈,因为它们无论如何都是私有的。上面也没有将闭包的工作与外部变量名联系起来。我的版本可以成为可重复使用的服务:
function fruitGetter(fruits) {
var index = 0, numberOfFruits = fruits.length;
function getNextFruit() {
render(fruits[_index]);
index = (_index + 1) % numberOfFruits;
}
return getNextFruit;
}
// ...
var getNextFruit = fruitGetter(someFruits);
var otherFruits = fruitGetter(["kumquat", "lychee", "mango"]);