Меня всегда учили, что наличие побочных эффектов в if
состоянии - это плохо. Я имею в виду;
if (conditionThenHandle()) {
// do effectively nothing
}
... в отличие от;
if (condition()) {
handle();
}
... и я понимаю это, и мои коллеги счастливы, потому что я не делаю этого, и мы все идем домой в 17:00 в пятницу, и у всех есть веселые выходные.
Теперь, ECMAScript5 введены такие методы , как every()
и some()
к Array
, и я нахожу их очень полезными. Они чище, чем у for (;;;)
, дают вам другую область и делают элемент доступным для переменной.
Однако при проверке входных данных я чаще всего использую every
/ some
в условии для проверки входных данных, а затем снова использую every
/ some
снова в теле для преобразования входных данных в пригодную для использования модель;
if (input.every(function (that) {
return typeof that === "number";
})) {
input.every(function (that) {
// Model.findById(that); etc
}
} else {
return;
}
... когда то, чем я хочу заниматься;
if (!input.every(function (that) {
var res = typeof that === "number";
if (res) {
// Model.findById(that); etc.
}
return res;
})) {
return;
}
... что дает мне побочные эффекты в if
состоянии, которое плохо.
Для сравнения, этот код будет выглядеть со старым for (;;;)
;
for (var i=0;i<input.length;i++) {
var curr = input[i];
if (typeof curr === "number") {
return;
}
// Model.findById(curr); etc.
}
Мои вопросы:
- Это определенно плохая практика?
- Использую ли я (mis | ab)
some
иevery
( должен ли я использоватьfor(;;;)
для этого?) - Есть ли лучший подход?
some
, я хочу сделать что-то с элементом, если я используюevery
, я хочу сделать что-то со всеми этими элементами ...some
иevery
не позволяю мне получить доступ к этой информации, поэтому я тоже не могу используйте их, или я должен добавить побочные эффекты.some
в моемif
состоянии , чтобы определить , имеет ли определенный элемент в массиве определенного свойства, 9/10 Мне нужно работать на этом элементе в моемif
теле; теперь, посколькуsome
мне не сообщается, какой из элементов обладает свойством (только «один сделал»), я могу либоsome
снова использовать его в теле (O (2n)), либо просто выполнить операцию внутри условия if ( что плохо, потому что это побочный эффект в голове).every
, конечно.Ответы:
Если я правильно понимаю вашу точку правильно, вы , кажется, неправильно использовать или злоупотребления
every
и ,some
но это немного неизбежно , если вы хотите изменить элементы ваших массивов непосредственно. Поправьте меня, если я ошибаюсь, но то, что вы пытаетесь сделать, это выяснить, имеет ли какой-то или каждый элемент в вашей последовательности определенное условие, а затем изменить эти элементы. Кроме того, ваш код, кажется, применяет что-то ко всем элементам, пока вы не найдете тот, который не проходит предикат, и я не думаю, что вы это делаете. В любом случае.Давайте возьмем ваш первый пример (слегка измененный)
То, что вы делаете здесь, на самом деле идет вразрез с духом концепций «некоторые / каждый / карта / уменьшение / фильтр / и т.д.».
Every
не предназначен для того, чтобы воздействовать на каждый элемент, который соответствует чему-либо, скорее он должен использоваться только для того, чтобы сообщать вам, есть ли каждый элемент в коллекции. Если вы хотите применить функцию ко всем элементам, для которых предикат оценивается как true, «хороший» способ сделать этоКроме того, вы можете использовать
foreach
вместо карты, чтобы изменить элементы на месте.Та же логика применима
some
, в основном:every
для проверки, если все элементы в массиве проходят некоторый тест.some
для проверки, если хотя бы один элемент в массиве проходит какой-либо тест.map
для возврата новый массив, содержащий 1 элемент (который является результатом функции по вашему выбору) для каждого элемента во входном массиве.filter
чтобы вернуть массив длиной 0 <length
<initial array length
элементов, все содержащиеся в исходном массиве и все проходящей проверку прилагаемого предиката.foreach
если вы хотите карту, но на местеreduce
если хотите объединить результаты массива в единый объектный результат (который может быть массивом, но не обязан).Чем больше вы их используете (и чем больше вы пишете код LISP), тем больше вы понимаете, как они связаны и как даже возможно эмулировать / реализовать одно с другими. Что важно в этих запросах и что действительно интересно, так это их семантика и то, как они действительно подталкивают вас к устранению вредных побочных эффектов в вашем коде.
РЕДАКТИРОВАТЬ (в свете комментариев): Допустим, вы хотите проверить, что каждый элемент является объектом, и преобразовать их в модель приложения, если они все действительны. Один из способов сделать это за один проход:
Таким образом, когда объект не проходит проверку, вы все равно продолжаете итерацию по всему массиву, что будет медленнее, чем просто проверка с помощью
every
. Тем не менее, большую часть времени ваш массив будет действительным (или я должен на это надеяться), поэтому в большинстве случаев вы выполняете один проход над вашим массивом и в итоге получаете пригодный для использования массив объектов модели приложения. Семантика будет соблюдаться, побочных эффектов не будет, и все будут счастливы!Обратите внимание, что вы также можете написать свой собственный запрос, похожий на foreach, который применил бы функцию ко всем элементам массива и вернул бы true / false, если они все прошли предикатный тест. Что-то вроде:
Хотя это изменило бы массив на месте.
Надеюсь, это поможет, было очень весело писать. Ура!
источник
if (input.every())
, чтобы убедиться, что каждый элемент является объектом (typeof el === "object && el !== null
) и т. д., а затем, если это проверяется, я хочу преобразовать каждый элемент в соответствующая модель приложения (которую, как вы сейчас упомянули,map()
я мог бы использоватьinput.map(function (el) { return new Model(el); });
; но не обязательно на месте .map()
мне придется дважды перебирать массив; один раз для проверки, а другой для преобразования. Однако, используя стандартнуюfor(;;;)
петлю, я мог бы сделать это с помощью одной итерации, но я не могу найти способ применитьevery
,some
,map
илиfilter
в этом сценарии, и выполнить только один проход, без нежелательного побочного -побочных эффектов или иного введения bad- практика.Побочные эффекты не в условии if, а в теле if. Вы только определили, следует ли выполнять это тело в фактическом состоянии. Здесь нет ничего плохого в вашем подходе.
источник
if
условия, толькоreturn
внутри существаif
; очевидно, я имею в виду пример кода, которому предшествует « то, что нужно делать, это; ...if
состоянии.