我想构建一个维护状态的javascript函数。这是我提出的一种模式,但是我脑子里的一些东西告诉我这是一种反模式。
function f() {
var state = 1;
f = function() {
return state++;
};
return f();
};
这有什么问题吗?如果是这样,有什么更好的方法?
答案 0 :(得分:17)
嗯,这是最好的方式的问题,但是(虽然我知道它有效)但是我对使用该函数覆盖自己感到有点不舒服。类似的模式不能做到但仍然使用几乎相同的闭包理念是这样的:
var f = function() {
var state = 1;
return function() {
return state++;
};
}();
或者这是另一种方式:
function f() {
return f.state++;
}
f.state = 1;
当然使用f.state
方法,优势和缺点(取决于您的需要)是.state
属性可以被其他代码读取和修改。
答案 1 :(得分:11)
通常,您设置闭包范围并返回有权访问该范围的函数。每次调用该函数时,只要该函数存在,状态就会保持不变。例如:
var statefulFunction = function() {
// set up closure scope
var state = 1;
// return function with access to the closure scope
return function() {
return state++;
};
}(); // immediately execute to return function with access to closure scope
var first = statefulFunction(); // first === 1
var second = statefulFunction(); // second === 2
另一种模式是创建一个闭包范围并使用可以访问该闭包范围的方法返回一个对象。例如:
var myStatefulObj = function() {
// set up closure scope
var state = 1;
// return object with methods to manipulate closure scope
return {
incr: function() {
state++;
},
decr: function() {
state--;
},
get: function() {
return state;
}
};
}();
myStatefulObj.incr();
var currState = myStatefulObj.get(); // currState === 2
myStatefulObj.decr();
currState = myStatefulObj.get(); // currState === 1
答案 2 :(得分:2)
实现这一目标的更好方法可能是使用Immediately-Invoked Function Expression (IIFE)封装您的州。
var f = (function () {
var state = 1;
return function() {
return state++;
};
}());
console.log(f()); // 1
console.log(f()); // 2