Основной ответ, конечно же, таков: разбить его на более мелкие кусочки, где каждый кусочек делает одну вещь хорошо.
Трудно быть более конкретным, не видя примера, но вы сказали, что у вас есть "... беспорядок условий внутри большого оператора switch ...", который определенно дает возможность для улучшения: вы можете перемещать содержимое каждый случай в свою функцию.
Если вы сделаете это, у вас есть два варианта: либо заставить функции работать исключительно с аргументами, которые вы передаете в них, что стремится сделать вещи более модульными, либо сделать замыкания функций, управляющие данными во внешней функции. Я бы сказал, что последний вариант менее идеален & mdash; для этих целей & mdash; но это может быть быстрее, и это будет "быстрый выигрыш".
Скажем, у нас изначально было:
function myBigFunction() {
var v1, v2, v3;
/* ...set v1, v2, and v3 to various things...*/
switch (condition) {
case foo:
/* ...do lots of stuff involving v1 and v2...*/
break;
case bar:
/* ...do lots of stuff involving v1 only...*/
break;
case charlie:
/* ...do lots of stuff involving v2 and v3...*/
break;
}
}
Тогда:
Первый вариант: полностью независимые функции :
function myBigFunction() {
var v1, v2, v3;
/* ...set v1, v2, and v3 to various things...*/
switch (condition) {
case foo:
doFooStuff(v1, v2);
break;
case bar:
doBarStuff(v1);
break;
case charlie:
doCharlieStuff(v2, v3);
break;
}
}
function doFooStuff(v1, v2) {
}
function doBarStuff(v1) {
}
function doCharlieStuff(v2, v3) {
}
... и, конечно, есть вероятность, что вам нужно, чтобы эти функции возвращали что-то, а затем обрабатывали это, например:
case foo:
v1 = doFooStuff(v1, v2);
break;
... если doFooStuff
необходимо обновить v1
. Если требуется обновить v1
и v2
, вы можете вернуть массив или создать свойства v1
и v2
для объекта, который вы передаете в doFooStuff
и т. Д. Вот пример использования свойств: Замените Свойства v1
и v2
с объектом (vdata
), который имеет свойства v1
и v2
:
var vdata = {
v1: "someInitialValue",
v2: "someInitialValue"
};
... тогда ваш звонок на doFooStuff
:
case foo:
doFooStuff(vdata);
break;
... что позволяет doFooStuff
обновлять v1
и v2
. Но будьте осторожны, вы не хотите создавать кухонную раковину со всеми переменными myBigFunction
, это принесло бы в жертву модульность.
Второй вариант: использование замыканий и непосредственная работа с данными родительской функции :
function myBigFunction() {
var v1, v2, v3;
/* ...set v1, v2, and v3 to various things...*/
switch (condition) {
case foo:
doFooStuff();
break;
case bar:
doBarStuff();
break;
case charlie:
doCharlieStuff();
break;
}
function doFooStuff() {
// work with v1 and v2 directly
}
function doBarStuff() {
// work with v1 directly
}
function doCharlieStuff() {
// work with v2 and v3 directly
}
}
Обратите внимание, что здесь различные подпрограммы являются замыканиями внутри myBigFunction
и поэтому имеют прямой доступ ко всем локальным переменным myBigFunction
. Это более модульный, но не совсем модульный подход первого варианта. Это также похоже на локальную версию вопроса о функциях, работающих с глобальными переменными: побочные эффекты легко вводятся и могут вызвать проблемы.
Первый вариант предпочтителен, но, если он нецелесообразен, второй вариант, по крайней мере, поможет вам сделать вашу основную логику более понятной. И, конечно, комбинация обоих может сработать.