Frachtkult-Programmierung ist das, was ein Programmierer tut, wenn er oder sie eine bestimmte Sprache oder ein bestimmtes Paradigma nicht gut genug beherrscht und so überflüssigen und möglicherweise schädlichen Code schreibt. Sie zieht ihren Kopf oft im Land von JavaScript auf. In diesem Artikel untersuche ich das Konzept der Cargo-Kult-Programmierung und Orte, auf die Sie in JavaScript achten müssen.
Dogmatische Regeln tauchen auf und breiten sich aus, bis sie als Norm gelten.
Cargo-Kultivierung wird manchmal als "extremes Festhalten an der Form statt Inhalt" definiert. Die Form beim Programmieren ist die Syntax, die Paradigmen, Stile und Muster, die wir verwenden. Der Inhalt ist die abstrakte Sache, die Sie durch Ihren Code darstellen möchten - der eigentliche Inhalt Ihres Programms. Eine Person mit fehlendem Verständnis in einem Bereich kopiert wahrscheinlich die Form anderer ohne wahres Verständnis, und daher kann ihr Inhalt - ihr Programm - leiden.
Die Frachtkultivierung ist in JavaScript merkwürdig, wahrscheinlich aufgrund der allgemein niedrigen Eintrittsbarriere in der Front-End-Entwicklungswelt. Sie können innerhalb von Sekunden eine HTML-Seite mit etwas JavaScript aufrüsten. Infolgedessen gibt es viele Menschen, die sich mit diesen Technologien so gut auskennen, dass sie sich wohl fühlen können, wenn sie Regeln für sich selbst und andere festlegen und auferlegen. Möglicherweise kopieren andere Neulinge diese Regeln. Dogmatische Regeln tauchen auf und breiten sich aus, bis sie als Norm gelten:
Eine Regel verbreitet sich weiter, bis ein Programmierer aufgrund seiner Beliebtheit nur eine bestimmte Technik verwendet, anstatt jeden spezifischen Anwendungsfall unabhängig zu betrachten.
Wenn Sie die Möglichkeit hatten, den witzigen Geplänkel und die Rhetorik des Softwareentwicklers im Laufe der Jahre mitzuerleben, haben Sie die Tendenz entdeckt, scheinbar kleine Dinge ausführlich zu diskutieren. Dinge wie das Semikolon, das Komma, das Leerzeichen oder die geschweifte Klammer.
Syntax wie Semikolons oder Leerzeichen scheinen rein formale Elemente zu sein, nicht inhaltlich. Viele dieser subtilen Syntaxregeln können jedoch erhebliche Auswirkungen auf JavaScript haben. Wenn Sie das 'Formular' nicht verstehen, können Sie den 'Inhalt' nicht verstehen.
In diesem Artikel werden wir also herausfinden, aus welchen Bereichen von JavaScript häufig fremdgefragt wird, das heißt, sie werden ohne Verständnis kopiert.
Wie JavaScript wirken kann… ein Bild aus Angus Crolls "The Politics of JavaScript" -PräsentationIn einer kürzlich erschienenen Präsentation mit dem Titel "The Politics Of JavaScript" hob Angus Croll einen der häufigsten Teile des JS-Dogmas hervor, von dem die Leute sich abschrecken:
if (typeof myObject.foo === 'undefined') …
Die meiste Zeit, wenn Sie so einen langatmigen Check durchführen nicht definiert
ist sinnlos. Die Technik wurde allgemein üblich, weil Leute andere Leute kopierten, nicht wegen ihres tatsächlichen Wertes.
Natürlich gibt es Zeiten, zu denen:
typeof x === 'undefined'
… Ist vorzuziehen:
x === undefiniert
Es gibt aber auch Zeiten, in denen Letzteres bevorzugt wird. Ein kurzer Überblick über die Optionen:
// Bestimmen, ob 'x' undefined ist: x === undefined typeof x == 'undefined' typeof x === 'undefined' x === void 0 // Bestimmen, ob 'x' undefined ist ODER null: x = = null x == undefiniert
Die Leute fingen an, die Art der
Ansatz, weil sie sich gegen:
nicht definiert
zu so etwas wahr
. Sie müssen sich fragen: "Ist es wahrscheinlich, dass jemand undefined überschrieben hat, und sollte mein Skript so dumm sein müssen??"Aber meistens schützen sie sich vor Sorgen. Es ist eine weitgehende Vermeidung, die Details kennen zu müssen. Die Kenntnis der Details kann Ihnen jedoch helfen. Jedes Zeichen Ihres Codes sollte einen bestimmten Zweck haben.
Die einzige Zeit, die Sie benötigen, um eine Art der
prüfen Auf nicht definiert
ist, wenn Sie nach einer Variablen suchen, die möglicherweise nicht deklariert wurde, z. Suche nach jQuery im globalen Bereich:
if (typeof jQuery! = 'undefined') //… jQuery verwenden
Die Sache ist, wenn jQuery tut existieren, dann können wir sicher sein, dass es ein Objekt ist - ein "wahres" Ding. Das wäre also ausreichend:
// oder: if (window.jQuery)
Nehmen wir etwas sehr allgemeines und allgemein als guten Rat an, nur mit strikter Gleichheit:
a === b
Strikte Gleichheit gilt als gut, weil sie Mehrdeutigkeit vermeidet. Es überprüft sowohl den Wert als auch den Typ, was bedeutet, dass wir uns nicht um impliziten Zwang kümmern müssen. Bei nicht strenger Gleichheit müssen wir uns jedoch Sorgen machen:
1 == 1 // wahr - okay, das ist gut 1 == "1" // wahr - hmm 1 == [1] // wahr - wat!?
Es scheint also ein vernünftiger Rat, nicht-strikte Gleichheit gänzlich zu vermeiden, oder? Nicht wirklich. Es gibt viele Situationen, in denen strikte Gleichheit große Mengen an Redundanz verursacht, und eine nicht strikte Gleichheit ist vorzuziehen.
Wenn Sie mit 100% iger Sicherheit wissen, dass die Typen beider Operanden gleich sind, können Sie die Notwendigkeit der strengen Gleichheit vermeiden. Zum Beispiel weiß ich immer, dass das Art der
Operator gibt eine Zeichenfolge zurück, und mein rechter Operand ist ebenfalls eine Zeichenfolge (z. B.. "Nummer"
):
// Mit strikten Entsprechungen vom Typ x === 'number' // Mit den nicht strikten Entsprechungen: typeof x == 'number'
Sie sind beide effektiv identisch. Ich schlage nicht unbedingt vor, dass wir in diesem Fall strikte Gleiche aufgeben - ich schlage vor, dass wir uns dessen bewusst bleiben, was wir tun, damit wir in jeder Situation die besten Entscheidungen treffen können.
Ein anderes sehr nützliches Beispiel ist, wenn Sie wissen möchten, ob ein Wert entweder ist Null
oder nicht definiert
. Mit strenger Gleichheit können Sie Folgendes tun:
if (Wert === undefined || Wert === Null) //…
Mit nicht strenger Gleichheit ist es viel einfacher:
if (value == null) //…
Hier gibt es keinen Haken - es tut genau das, was wir wollen, nur, was weniger sichtbar ist. Aber wenn wir die Sprache kennen, was ist dann das Problem? Es ist genau dort in der Spezifikation:
Der Vergleich x == y
, woher x
und y
sind Werte, produziert wahr
oder falsch
. Ein solcher Vergleich wird wie folgt durchgeführt:
Wenn Sie JavaScript mit der Absicht schreiben, es gelesen zu werden, wenn überhaupt, von Leuten, die JavaScript kennen, dann würde ich argumentieren, dass Sie sich nicht schlecht fühlen sollten, wenn Sie implizite Sprachregeln wie diese nutzen.
hasOwnProperty
Das hasOwnProperty
Diese Methode wird verwendet, um zu bestimmen, ob eine Eigenschaft direkt einem Objekt gehört. Ist es häufig in gefunden? für in
Schleifen, um sicherzustellen, dass Sie nur mit direkten Eigenschaften und nicht mit geerbten Eigenschaften arbeiten.
for (var i in object) if (object.hasOwnProperty (i)) // Mit 'object [i]' können wir Sachen erledigen.
Es ist wichtig zu wissen, dass die für in
Die Anweisung wird nur durch enumarable-Eigenschaften durchlaufen. Native vererbte Methoden sind zum Beispiel nicht aufzuzählen und Sie müssen sich sowieso keine Sorgen um sie machen.
Das hasOwnProperty
check verhindert insbesondere, dass Sie Eigenschaften berühren, die Sie oder ein Skript eines Drittanbieters definiert haben, d. h. wenn der Prototyp Ihres Objekts über aufzählbare Eigenschaften verfügt.
Wenn Sie wissen, dass der Prototyp Ihres Objekts (oder dessen Prototyp etc.) hat also keine aufzählbaren Eigenschaften Sie müssen sich keine Sorgen machen über die Verwendung hasOwnProperty
in deiner für in
Schleifen Wenn Ihr Objekt über ES5 initialisiert wird Object.create (null)
, dann können Sie nicht einmal anrufen hasOwnProperty
direkt auf dem Objekt (Kein Prototyp bedeutet keine ererbten systemeigenen Methoden). Dies bedeutet, dass mit hasOwnProperty
standardmäßig in allen Ihren für in
Schleifen können tatsächlich manchmal brechen.
Eine mögliche Lösung für Objekte mit Null
Prototypen verwenden einen gespeicherten Verweis auf hasOwnProperty
, wie so:
var hasOwnProperty = Object.prototype.hasOwnProperty; // Später in Ihrem Code: for (var i in someObject) if (hasOwnProperty.call (someObject, i)) //…
Das funktioniert auch, wenn das Objekt keinen Prototyp hat (im Fall von Object.create (null)
). Aber wir sollten das natürlich erst tun, wenn wir wissen, dass wir es brauchen. Wenn Sie ein Skript eines Drittanbieters für eine "feindliche" Umgebung schreiben, überprüfen Sie die Auflistung der geerbten Eigenschaften. Andernfalls ist es möglicherweise nicht immer erforderlich.
Hinweis: IE9 und Safari 2.0 erschweren die Sache zusätzlich, wenn Sie versuchen, Aufzählungsmerkmale zu identifizieren, die bereits als nicht auflistbar definiert sind. Es lohnt sich, eine wirklich Cross-Browser für die Implementierung der eigenen Schleife zu testen.
Zum Schluss: Ihre Verwendung von hasOwnProperty
sollte von dem Objekt abhängen, das überlaufen wird. Es hängt davon ab, welche Annahmen Sie sicher treffen können. Sich blind schützen mit der hasOwnProperty
wird nicht in allen Fällen ausreichen. Seien Sie auch bei Cross-Browser-Unterschieden vorsichtig.
Eine andere häufige Redundanz, die sich in JS-Code einschleicht, ist die Klammer. Innerhalb von Ausdrücken wird es verwendet, um eine bestimmte Gruppierung von Unterausdrücken zu erzwingen. Ohne sie sind Sie den Prioritäten und Assoziationen der Operatoren ausgeliefert. Zum Beispiel:
A && B || C A && (B || C) (A && B) || C
Einer davon ist nicht wie der andere. Die Klammern erzwingen eine bestimmte Gruppierung, und viele Leute bevorzugen die zusätzliche Klarheit. In diesem Fall hat der logische AND-Operator eine höhere Priorität als der logische OR-Operator. Dies bedeutet, dass die erste und die letzte Zeile gleichwertig sind. Die zweite Zeile ist eine völlig andere logische Operation.
Höhere Priorität bedeutet, dass sie in einer Reihe von Operationen vor anderen Operationen auftritt.
Um diese Komplexität zu vermeiden, entscheiden sich Entwickler häufig für eine "Klammerrichtlinie". Sie fügen Klammern hinzu, bis klar ist, welche Operationen ausgeführt werden, sowohl für Sie als auch für potenzielle Leser des Codes. Man kann argumentieren, dass diese Ausführlichkeit dazu führt, dass die Dinge weniger klar sind.
Für einen Leser ist es manchmal schwierig. Man muss bedenken, dass eventuell gegebene Klammern hinzugefügt wurden, weil:
Nehmen Sie dieses Beispiel:
A && B? doFoo (): doBaz ()
Ohne Kenntnis der Vorrangregeln für Operatoren sehen wir hier zwei mögliche Operationen:
(A && B)? doFoo (): doBaz () A && (B? doFoo (): doBaz ())
In diesem Fall hat das logische AND die höhere Priorität, was bedeutet, dass der entsprechende Ausdruck in Klammern lautet:
(A && B)? doFoo (): doBaz ()
Wir sollten uns jedoch nicht verpflichtet fühlen, diese Klammern in unseren Code aufzunehmen. Es geschieht implizit. Sobald wir erkennen, dass dies implizit geschieht, können wir es ignorieren und uns auf das Programm selbst konzentrieren.
Es gibt natürlich gültige Argumente, um die Klammern beizubehalten, wenn die implizite Gruppierung unklar ist. Das hängt wirklich von Ihnen ab und von dem, was Sie möchten. Ich möchte Sie jedoch dazu auffordern, die Präzedenzfälle zu lernen, und dann können Sie völlig befugt sein, den besten Weg einzuschlagen, abhängig von dem spezifischen Code, mit dem Sie sich befassen.
Es ist nicht selten, redundante Anführungszeichen in Objektliteralen zu sehen:
var data = 'date': '2011-01-01', 'id': 3243, 'action': 'UPDATE', 'related': '1253': 2, '3411': 3;
Zusätzlich zu Strings können Sie in JavaScript gültige Bezeichnernamen und -nummern als Objekt-Literal-Schlüssel verwenden.
var data = date: '2011-01-01', id: 3243, Aktion: 'UPDATE', verwandt: 1253: 2, 3411: 3;
Manchmal bevorzugen Sie möglicherweise die zusätzliche Konsistenz der Verwendung von Anführungszeichen, insbesondere wenn ein Feldname in JavaScript ein reserviertes Wort ist (wie 'class' oder 'instanceof'). Und das ist gut so.
Die Verwendung von Anführungszeichen ist keine schlechte Sache. Aber es ist überflüssig. Zu wissen, dass man sie nicht benutzen muss, ist die halbe gewonnene Schlacht. Sie haben jetzt die Wahl, was Sie wollen.
Es gibt eine Menge subjektiver Präferenzen, wenn es um die Platzierung von Interpunktionen in der Programmierung geht. In letzter Zeit war die JavaScript-Welt voller Rhetorik und Unzufriedenheit über das Komma.
Das Initialisieren eines Objekts in traditionell idiomatischem JavaScript sieht folgendermaßen aus:
var obj = a: 1, b: 2, c: 3;
Es gibt einen alternativen Ansatz, der jedoch an Bedeutung gewonnen hat:
var obj = a: 1, b: 2, c: 3;
Der vermeintliche Vorteil der Platzierung der Kommas vor jedem Schlüsselwertpaar (außer dem ersten) besteht darin, dass Sie nur eine Zeile berühren müssen, um eine Eigenschaft zu entfernen. Mit dem traditionellen Ansatz müssten Sie "entfernen"c: 3
"und dann das nachfolgende Komma in der Zeile darüber. Aber mit dem Komma-First-Ansatz können Sie einfach entfernen", c: 3
"Die Befürworter behaupten, dies mache nachkommende Kommas unwahrscheinlicher und reinige auch die Source-Control-Differenzen.
Gegner behaupten jedoch, dass dieser Ansatz nur durch das Einführen eines neuen Problems mit dem führenden Komma das Problem des Nachkommas beseitigen kann. Versuchen Sie, die erste Zeile zu entfernen, und in der nächsten Zeile wird ein führendes Komma angezeigt. Dies wird von Comma-First-Befürwortern als eine gute Sache angesehen, da ein führendes Komma sofort einen SyntaxError werfen würde. Ein nachfolgendes Komma wirft jedoch nichts außer IE6 und 7. Wenn also der Entwickler seine JS in diesen IE-Versionen nicht testet, können sich die nachfolgenden Kommas oft in den Produktionscode einschleichen, was nie gut ist. Ein führendes Komma wirft in allen Umgebungen, daher ist es weniger wahrscheinlich, dass es übersehen wird.
Natürlich könnte man argumentieren, dass diese ganze Sache irrelevant ist. Wir sollten wahrscheinlich Linters wie JSLint oder den besseren JSHint verwenden. Dann können wir die Interpunktion und die Platzierung von Leerzeichen verwenden, die für uns und unsere Mitarbeiter am sinnvollsten ist.
Lassen Sie uns noch nicht einmal mit dem Komma-ersten Stil in Variablendeklarationen beginnen…
var a = 1, b = 2, c = 3;
Wir sollten uns bemühen, die Sprachen, die wir verwenden, so gut zu lernen, dass wir die Ladungskultivierung und die übermäßigen Schutztechniken der Catch-All-Techniken vermeiden können. Und wir sollten unseren Mitarbeitern und anderen Entwicklern vertrauen, dasselbe zu tun.
Wir haben auch über den Verzicht auf Cruft gesprochen, um die Eigenheiten einer Sprache und implizite Regeln zu nutzen. Für einige sind dies Wartbarkeitsprobleme, insbesondere wenn sich jemand, der eine neue Sprache erworben hat, an den Code heranarbeitet. Zum Beispiel: Was ist, wenn sie nicht wissen, was JavaScripts schwache vs. strikte Gleichheit ist??
Zum Thema Wartbarkeit erinnern wir an dieses berühmte Zitat:
Immer Code, als ob die Person, die Ihren Code erhalten hat, ein gewalttätiger Psychopath ist, der weiß, wo Sie leben.
Ich weiß nicht, ob das wirklich ein guter Rat ist. Selbst metaphorisch betrachtet, deutet dies auf ein Misstrauen gegenüber der Kompetenz des fiktionalen Betreibers hin - und auf die Notwendigkeit, sich vor allem über ihr Verständnis Sorgen zu machen. Ich würde lieber Code schreiben, in dem Wissen, dass Leute, die ihre Sachen kennen, dafür sorgen werden. Als möglichen Widerspruch oder sogar als Nachtrag zu diesem Zitat biete ich an:
Immer Code, als ob die Person, die Ihren Code verwaltet, sich mit der Sprache und ihren Konstrukten auskennt und versucht, durch das Lesen des Codes Verständnis für den Problembereich zu erlangen.
Dies mag zwar nicht immer wahr sein, aber wir sollten danach suchen. Wir sollten uns darum bemühen, dass die Leute, die an einer bestimmten Technologie arbeiten, über das nötige Verständnis verfügen. Der gelehrte Frachtschreiber sagt:
Wenn ich für immer zu einem niedrigeren Verständnisniveau in meinem Code komme - leise gehen - strikte Einhaltung von Konventionen und Stilrichtlinien und Dingen, die die "Experten" tun, dann kann ich mein Verständnis nicht verbessern oder einen Vorteil daraus ziehen Sprache in all ihrer Seltsamkeit und Schönheit. Ich bin glücklich und glückselig in dieser Welt der Regeln und Absoluten angesiedelt, aber um weiterzukommen, muss ich diese Welt verlassen und ein höheres Verständnis annehmen.