Javascript: создание функции с состоянием
Я хочу создать функцию javascript, которая поддерживает состояние. Вот образец, который я придумал, но что-то в глубине моего разума говорит мне, что это анти-шаблон.
function f() {
var state = 1;
f = function() {
return state++;
};
return f();
};
Что-то не так с этим? Если да, то какой лучший подход?
Ответы
Ответ 1
Ну, это вопрос мнения, какой лучший способ, но (хотя я знаю, что это работает) Мне немного неудобно, когда функция перезаписывает себя. Аналогичная модель, которая не делает этого, но по-прежнему использует практически ту же идею закрытия, такова:
var f = function() {
var state = 1;
return function() {
return state++;
};
}();
Или вот другой способ:
function f() {
return f.state++;
}
f.state = 1;
Конечно, с f.state
метода f.state
преимущество и недостаток (в зависимости от ваших потребностей) заключается в том, что свойство .state
может быть прочитано и изменено другим кодом.
Ответ 2
Обычно вы устанавливаете область закрытия и возвращаете функцию, которая имеет доступ к этой области. Каждый раз, когда эта функция теперь вызывается, состояние будет оставаться до тех пор, пока эта функция существует. Пример:
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
Ответ 3
Лучшим способом достижения этого может быть использование выражения с мгновенной вызывной функцией (IIFE) для инкапсуляции вашего состояния.
var f = (function () {
var state = 1;
return function() {
return state++;
};
}());
console.log(f()); // 1
console.log(f()); // 2