Mir wurde immer beigebracht, dass Nebenwirkungen in einem if
Zustand schlecht sind. Was ich meine ist;
if (conditionThenHandle()) {
// do effectively nothing
}
... im Gegensatz zu;
if (condition()) {
handle();
}
... und ich verstehe das, und meine Kollegen sind glücklich, weil ich es nicht tue, und wir gehen alle freitags um 17:00 Uhr nach Hause und alle haben ein fröhliches Wochenende.
Jetzt hat ECMAScript5 Methoden wie every()
und some()
zu eingeführt Array
, und ich finde sie sehr nützlich. Sie sind sauberer als for (;;;)
die anderen, geben Ihnen einen anderen Bereich und machen das Element durch eine Variable zugänglich.
Bei der Validierung von Eingaben verwende ich jedoch häufig every
/ some
in der Bedingung, die Eingabe zu validieren, und verwende dann every
/ some
erneut im Body, um die Eingabe in ein verwendbares Modell umzuwandeln.
if (input.every(function (that) {
return typeof that === "number";
})) {
input.every(function (that) {
// Model.findById(that); etc
}
} else {
return;
}
... wenn ich etwas tun möchte ;
if (!input.every(function (that) {
var res = typeof that === "number";
if (res) {
// Model.findById(that); etc.
}
return res;
})) {
return;
}
... was mir Nebenwirkungen in einem if
Zustand gibt, der schlecht ist.
Im Vergleich dazu ist dies der Code, mit dem ein alter Code aussehen würde for (;;;)
.
for (var i=0;i<input.length;i++) {
var curr = input[i];
if (typeof curr === "number") {
return;
}
// Model.findById(curr); etc.
}
Meine Fragen sind:
- Ist das definitiv eine schlechte Praxis?
- Benutze ich (mis | ab)
some
undevery
( sollte ich dafür ein verwendenfor(;;;)
?) - Gibt es einen besseren Ansatz?
quelle
some
, möchte ich etwas mit dem Element machen, wenn ich benutzeevery
, möchte ich all diesen Elementen etwas antun ...some
undevery
mich nicht auf diese Informationen zugreifen lassen, also kann ich es auch nicht benutze sie, oder ich muss Nebenwirkungen hinzufügen.some
in meinemif
Zustand , um zu bestimmen , ob ein bestimmtes Element in dem Array eine bestimmte Eigenschaft aufweist, 9/10 Ich muß zum Betrieb auf diesem Elemente in meinemif
Körper; Jetzt, dasome
mir nicht gesagt wird, welches der Elemente die Eigenschaft aufweist (nur "eines hat es getan"), kann ich es entwedersome
wieder im Körper verwenden (O (2n)) oder ich kann die Operation einfach innerhalb der if- Bedingung ausführen ( was schlecht ist, weil es eine Nebenwirkung im Kopf ist).every
natürlich auch für.Antworten:
Wenn ich Ihren Standpunkt richtig verstehe, scheinen Sie ihn zu missbrauchen oder zu missbrauchen,
every
undsome
es ist ein wenig unvermeidlich, wenn Sie die Elemente Ihrer Arrays direkt ändern möchten. Korrigieren Sie mich, wenn ich falsch liege, aber Sie versuchen herauszufinden, ob einige oder jedes Element in Ihrer Sequenz eine bestimmte Bedingung aufweist, und ändern Sie diese Elemente. Außerdem scheint Ihr Code etwas auf alle Elemente anzuwenden, bis Sie eines finden, das das Prädikat nicht erfüllt, und ich glaube nicht, dass Sie dies beabsichtigen. Sowieso.Nehmen wir Ihr erstes Beispiel (leicht modifiziert)
Was Sie hier tun, widerspricht tatsächlich ein wenig dem Geist einiger / jeder / map / redu / filter / etc-Konzepte.
Every
soll nicht verwendet werden, um jeden Gegenstand zu beeinflussen, der etwas entspricht, sondern sollte nur verwendet werden, um Ihnen mitzuteilen, ob jeder Gegenstand in einer Sammlung dies tut. Wenn Sie eine Funktion auf alle Elemente anwenden möchten, für die ein Prädikat den Wert true hat, ist dies der "gute" WegAlternativ können Sie
foreach
anstelle der Karte die Elemente an Ort und Stelle ändern.Die gleiche Logik gilt im
some
Grunde für:every
testen, ob alle Elemente in einem Array einen Test bestehen.some
testen, ob mindestens ein Element in einem Array einen Test besteht.map
für jedes Element in einem Eingabearray ein neues Array zurück, das 1 Element enthält (das Ergebnis einer Funktion Ihrer Wahl).filter
ein Array der Länge 0 <zurücklength
<initial array length
Elemente, die alle in der ursprünglichen Anordnung enthalten und alle mitgelieferten Prädikat Test bestanden.foreach
wenn Sie Karte aber an Ort und Stelle möchtenreduce
diese Option, wenn Sie die Ergebnisse eines Arrays in einem einzelnen Objektergebnis kombinieren möchten (das ein Array sein kann, aber nicht muss).Je häufiger Sie sie verwenden (und je mehr Sie LISP-Code schreiben), desto mehr erkennen Sie, wie sie zusammenhängen und wie es sogar möglich ist, eine mit den anderen zu emulieren / zu implementieren. Was bei diesen Abfragen mächtig und wirklich interessant ist, ist ihre Semantik und wie sie Sie wirklich dazu bringen, schädliche Nebenwirkungen in Ihrem Code zu beseitigen.
BEARBEITEN (im Lichte von Kommentaren): Angenommen, Sie möchten überprüfen, ob jedes Element ein Objekt ist, und sie in ein Anwendungsmodell konvertieren, wenn alle gültig sind. Eine Möglichkeit, dies in einem einzigen Durchgang zu tun, wäre:
Auf diese Weise durchlaufen Sie immer noch das gesamte Array, wenn ein Objekt die Validierung nicht besteht. Dies wäre langsamer als nur die Validierung mit
every
. In den meisten Fällen ist Ihr Array jedoch gültig (oder ich sollte es hoffen). In den meisten Fällen führen Sie einen einzelnen Durchlauf über Ihr Array durch und erhalten ein verwendbares Array von Anwendungsmodellobjekten. Die Semantik wird respektiert, Nebenwirkungen vermieden und alle werden glücklich sein!Beachten Sie, dass Sie ähnlich wie foreach auch eine eigene Abfrage schreiben können, die eine Funktion auf alle Mitglieder eines Arrays anwendet und true / false zurückgibt, wenn alle einen Prädikattest bestehen. So etwas wie:
Obwohl dies das Array an Ort und Stelle ändern würde.
Ich hoffe das hilft, es hat sehr viel Spaß gemacht zu schreiben. Prost!
quelle
if (input.every())
, dass jedes Element zu überprüfen , ist ein Objekt (typeof el === "object && el !== null
) etc, dann , wenn dass validates, ich jedes Element konvertieren will in die jeweiligen Anwendungsmodell (die jetzt erwähnen Siemap()
ich verwenden könnteinput.map(function (el) { return new Model(el); });
, aber nicht unbedingt an Ort und Stelle .map()
ich auch dann zweimal über das Array iterieren muss; einmal zu validieren und ein anderes zu konvertieren. Um jedoch einen Standard mitfor(;;;)
Schleife, könnte ich tue dies mit einer Iteration, aber ich kann nicht einen Weg finden , giltevery
,some
,map
oderfilter
in diesem Szenario und führen nur einen Pass, ohne dass unerwünschte-Nebenwirkungen oder auf andere Weise der Einführung Bad- trainieren.Die Nebenwirkungen sind nicht im if-Zustand, sondern im if-Körper. Sie haben nur festgelegt, ob dieser Körper im tatsächlichen Zustand ausgeführt werden soll oder nicht. An Ihrem Ansatz ist hier nichts auszusetzen.
quelle
if
Zustands, nur dasreturn
Wesen befindet sich imif
Körper des Körpers. Offensichtlich spreche ich über das Codebeispiel, dem vorangestellt ist: " Was ich tun möchte, ist: ...if
Zustand.