Welche allgemeinen Tipps haben Sie zum Golfen in JavaScript? Ich bin auf der Suche nach Ideen, die sich auf Code-Golf-Probleme im Allgemeinen anwenden lassen, die zumindest etwas spezifisch für JavaScript sind (z. B. "Kommentare entfernen" ist keine Antwort).
Hinweis: Siehe auch Tipps zum Golfen in ECMAScript 6 und höher
code-golf
tips
javascript
mellamokb
quelle
quelle
var
) zu schreiben. Und sollte JavaScript Golf Code eine Funktion sein oder etwas direkt ausgeben? Ich denke ehrlich, das kann viel bewirken.Antworten:
Lust auf Loops
Sie können die standard for-Schleife auf nicht standardmäßige Weise verwenden
ist im Wesentlichen gleichbedeutend mit:
Ein guter Trick ist es, den Code mit einer
while
Schleife zu schreiben und ihn dann in diea,b,c
Teile einerfor
Schleife zu teilen .Ein paar Beispiele, die ich geschrieben habe :
Verkette deine Setter
Wenn Sie mehrere Werte initialisieren oder zurücksetzen, verketten Sie den Wert mit allen Variablen, die ihn benötigen:
Implizites Casting
Überprüfen Sie Ihre Typen nicht, sondern verwenden Sie sie so, wie sie sind.
parseInt()
kostet10
Zeichen. Wenn Sie aus einer Zeichenfolge streichen müssen, müssen Sie kreativ sein:Vermeiden Sie Semikolons
JavaScript verfügt über eine automatische Semikoloneinfügung. Verwenden Sie es oft und gut.
Einzeiler
Sparen Sie an den Klammern, indem Sie so viel wie möglich in einzelne Zeilen oder Parameter schieben:
Increment / Decrement-Operatoren
und
kann leicht umgeschrieben werden als
und
beziehungsweise.
Verwenden Sie
this
oderself
anstelle vonwindow
im globalen KontextSelbsterklärende 2-Zeichen-Ersparnis.
Verwenden Sie die Klammernotation für den wiederholten Zugriff auf Eigenschaften
Dies ist definitiv ein Spagat zwischen der Länge des Eigenschaftsnamens und der Anzahl der Zugriffe. Anstatt
a.longFunctionName()
zweimal mit Punktnotation aufzurufen , ist es kürzer, den Namen zu speichern und die Funktion in Klammern aufzurufen:-vs-
Dies ist besonders effektiv bei Funktionen, auf
document.getElementById
die reduziert werden kannd[e]
.Hinweis:
Bei Verwendung der Klammernotation sind die Kosten
6 + name.length
beim ersten Mal Zeichen. Jeder weitere Zugriff kostet3
Zeichen.Bei der Punktnotation kosten alle Zugriffe
name.length + 1
(+1 für die.
) Zeichen.Verwenden Sie diese Methode, wenn
6 + name.length + (3 * (accesses - 1)) < accesses * (name.length + 1)
.len = Länge des Eigenschaftsnamens
i = Mindestzugriffe, um die Vorteile zu nutzen
Die Anzahl der Zugriffe kann auch mehrere Objekte umfassen. Wenn Sie
.length
in verschiedenen Arrays mindestens viermal zugreifen , können Sie dieselbe Variable verwenden, die die Zeichenfolge enthält'length'
.quelle
c = ~~a-~~b
sollte seinc = ~~a+~~b
. Sie können auch implizit in eine Ganzzahl umwandeln|0
, indem Sie beispielsweise Folgendes verwendenMath.random()*6|0
.a
undb
Zeichenfolgen sind, können Sie diese+a+b
in Zahlen konvertieren und hinzufügen.d- -b
eines Tages in meinem Code verwenden ...a.f=a.longfunctionname;a.f(b);a.f(c);a.f(d)
Teilen mit Zahlen, um die Anführungszeichen zu speichern:
quelle
.split`...`
"alpha,bravo,charlie".split`,`
Verwenden Sie den Komma-Operator, um geschweifte Klammern zu vermeiden ( gilt auch für C ):
Anstatt von
Das ist ein Zeichen länger.
quelle
Kürzere Zufallszahlengenerierung
Wenn Sie einen zufälligen Booleschen Wert (
0
oder1
) benötigen :Wenn Sie eine zufällige Ganzzahl benötigen
0 <= n < 1337
:Dies funktioniert, weil a
Date
intern in JavaScript als die Anzahl der Millisekunden seit einer Epoche gespeichertnew Date
ist.123somebignumber456
Wenn Sie also versuchen, eine Ganzzahlberechnung durchzuführen, wird dies erzwungen.Natürlich sind diese "zufälligen" Zahlen nicht so zufällig, besonders wenn Sie sie mehrere Male hintereinander aufrufen. Denken Sie also daran.
quelle
Sie können die Objektliteralform von get / set verwenden, um die Verwendung des Schlüsselworts zu vermeiden
function
.quelle
Dieser ist weniger bekannt und wird seltener verwendet, kann aber beeindruckend sein, wenn er in der richtigen Situation verwendet wird. Betrachten Sie eine Funktion, die keine Argumente akzeptiert und beim Aufruf immer eine andere Zahl zurückgibt, und die zurückgegebene Zahl wird in einer Berechnung verwendet:
Normalerweise können Sie diese Funktion mit einem einzigen Variablennamen abkürzen:
Ein besserer Weg, die Länge zu reduzieren, ist der Missbrauch
valueOf
, wodurch Sie 2 Zeichen pro Aufruf sparen. Nützlich, wenn Sie die Funktion mehr als fünfmal aufrufen:quelle
let a=[5,6,7,8,9,10,11,12].map(x=>x*Math.random()|0)
oderlet a=Array(7).map((_,i)=>i*Math.random()|0+5)
36 bzw. 42 Bytes gespeichert.r()
oder kürzer machen?r={valueOf:Math.random}
Das ist einfach genial: DKurzschlussbetreiber ausnutzen
Anstatt lange
if
Anweisungen oder ternäre Operatoren zu verwenden, können Sie Ihren Code verwenden&&
und||
verkürzen. Zum Beispiel:kann werden
Der
||
Operator wird häufig auf folgende Weise zum Festlegen von Standardeinstellungen verwendet:Dies ist das gleiche wie beim Schreiben
Erstellen sich wiederholender Zeichenfolgen mit Array
Wenn Sie eine lange Zeichenfolge eines bestimmten Zeichens initialisieren möchten, können Sie dazu ein Array mit einer Länge von n + 1 erstellen , wobei n die Häufigkeit ist, mit der Sie das Zeichen wiederholen möchten:
Je größer die Saite, desto größer die Ersparnis.
Zahlen analysieren
Verwenden Sie
+
und~
-Operatoren anstelle vonparseFloat()
oder,parseInt()
wenn Sie einen Zeichenfolgentyp, der nur eine Zahl ist, zu einem Zahlentyp zusammenfassen:Seien Sie jedoch vorsichtig, andere Typen können mit diesen Operatoren verschmolzen werden (dies
true
würde beispielsweise zu1
einer leeren Zeichenfolge werden ), oder eine Zeichenfolge, die nur Leerzeichen enthält , würde zu einer Zeichenfolge0
. Dies kann jedoch unter bestimmten Umständen nützlich sein.quelle
str.repeat(count)
Schleichen Sie die Variableninitialisierung in den prompt () - Aufruf ein, um Benutzereingaben zu erhalten
anstatt zu verwenden
Als Nebeneffekt wird der Eingabewert im Eingabeaufforderungsfenster angezeigt, während 1 Zeichen gespeichert wird.
quelle
[1,2,3].join('',i=5)
wenn ein Paar geschweifte Klammern gespeichert werden.i=5,[1,2,3].join()
.Für Schleifen verschachtelt kombinieren:
Beispiel mit unterschiedlichen Werten für
i
/j
:quelle
i*j
und die Divisions- / Moduloperatoren rufen die einzelnen Werte voni
und abj
.Unicode-Verknüpfungen
Wenn Sie bei einer großen Golfherausforderung eine verdammt gute eingebaute Immobilie nutzen, können Sie jede Immobilie einem Ein-Zeichen-Äquivalent zuordnen:
Nachdem Sie den obigen Code ausgeführt haben, können Sie ihn folgendermaßen verwenden:
"foo".Č(/.*/,'bar') // replaces foo with bar
Dies kostet 118 Byte und ist in bestimmten Situationen möglicherweise nicht sinnvoll
Es kann browserabhängig sein und ich bin nicht sicher, ob es kürzer ist als
with(Array){join(foo),...}
Variablen oder sie als verwendete Eigenschaften definiert,with(Array){j=join,m=map...}
aber es ist trotzdem erwähnenswert.quelle
Math
da es kein.prototype
Attribut hat. AlsMath
ich das entfernte, schaffte ich es, dies auf ein 114-Byte-Snippet herunterzuspielen, das sie alle Einzelbyte-Buchstaben zuweist. Sie finden es hier .À
-ÿ
, die noch je 1 Byte in der ISO-8859-1 - Codierung (die JS unterstützt). In Firefox 50 setzt dies leider die.localeCompare
Methode auf×
, aber das sollte normalerweise kein Problem sein. QuelleDas Umwandeln einer
while
Schleife in einefor
Schleife ist häufig äquivalent:In der zweiten Form kann die Variableninitialisierung kombiniert werden:
Beachten Sie, dass das zweite Formular ein Zeichen kürzer als das erste Formular ist.
quelle
Ausnahmefehler
Falls Zeichenketten- / Zeichenliterale nicht zulässig sind, können Sie einen try catch-Block verwenden:
jetzt
str
gleich"something"
Wenn mehr Zeichenketten benötigt werden, können Sie diese mit einer Zahl verketten (zB Nullen).
jetzt
arr
gleich["something", "foo", "bar", " is not defined"]
quelle
Wenn Sie eine Variable
1
in jeder Iteration einer Schleife initialisieren (z. B. eine Variable in einer äußeren Schleife für eine innere Schleife zurücksetzen), wie folgt (aus meiner Antwort auf diese Frage ):Da das Ergebnis einer Bedingung immer dann
j++<=n
ist,1
wenn es wahr ist, können Sie die Bedingung einfach direkt der Variablen zuweisen (denn wenn sie falsch wird, wird die Schleife nicht mehr ausgeführt und spielt keine Rolle mehr):Normalerweise können Sie mit dieser Methode 2 Zeichen speichern . Grüße an
@ugoren
für die Idee in den Kommentaren zu dieser Antwort.In einem anderen Beispiel habe ich diesen Trick auch auf meine Antwort hier mit dem Ausdruck
w=r=++c<S.length
in meiner äußeren for-Schleife angewendet und insgesamt 4 Zeichen gespeichert.quelle
Wenn Sie (für den Moment) bestimmte Spidermonkey-Skripte akzeptieren können, können Sie die Pfeilfunktionen von ECMAScript 6 verwenden . Anstatt wie folgt Code zu schreiben.
Sie können es so kürzen.
quelle
Wenn Sie nach NaN suchen müssen, verwenden Sie nicht
isNaN(x)
, sondern verwenden Siex!=x
, was kürzer ist und auch funktioniert.Beachten Sie, dass dies nur funktioniert, wenn
typeof(x) === "number"
; Wenn es sich zum Beispiel um eine Zeichenfolge handelt, wirdisNaN("string")
zurückgegebentrue
, aber"string" != "string"
zurückgegebenfalse
. Vielen Dank an Cyoce für diesen Hinweis!quelle
isNaN("string")
Renditentrue
, während"string"!="string"
Erträgefalse
(natürlich)if(!x){
, wenn SieNaN
explizit erkennen.x
auf Nummer,+x!=+x
entsprichtisNaN(x)
, jedoch immer noch 2 Zeichen kürzer. Dann wird+"string"!=+"string"
true zurückgegeben.Array Summe / Produkt / Quotient
ES5 : 17 Bytes
ES6 : 15 Bytes
Natürlich können Sie das
+
für alles tauschen, was Sie wollen, zB*
für ein Produkt oder einen/
Quotienten.quelle
Verwenden Sie eine bitweise Operation, um eine Zahl auf Null zu runden:
(Quelle: Zufälliges Würfelkippen )
Die Operatorrangfolge bestimmt, welche in Ihrem Programm kürzer ist.
quelle
n=prompt()|0
. H.Math.floor
ist furchtbar langsam ... sollte fast nicht verwendet werden, würde ich sagen.Schleifentipp I
Sie können
1
Zeichen beim Schleifen speichern , indem Siei
das zuletzt verwendete ändern :Hinweis: funktioniert auch mit
--
(aber ändern Sie die Schleife entsprechend, um Endlosschleifen zu vermeiden)Looping Tip II
Es gibt bestimmte Szenarien, in denen Sie ein Zeichen speichern können, indem Sie mit dem inkrementierenden Operator und den Werten spielen:
Hinweis: Sie müssen zum Beispiel aufpassen, wenn
0 to -1
. und9 to 10, 99 to 100
so lange herumspielen, bis Sie einen Weg finden, den Charakter zu rettenquelle
Verwenden Sie
^
anstelle von!=
oder==
beim Vergleich mit einer GanzzahlErsetzen Sie Aufrufe der integrierten mathematischen Funktionen durch kürzere Ausdrücke
quelle
-
statt!=
für ganze Zahlen auch einfach verwenden . Zum Beispieln!=1?a:b
wäre gleichbedeutend mitn-1?a:b
Bemerkenswert ist, dass Sie in einigen Fällen anstelle von Null eine Zeichenfolge verwenden können, um hier und da ein paar Bytes in Schleifen zu speichern:
quelle
Sehr einfach, trotzdem hatte es niemand erwähnt.
Wenn Sie verwenden
Math.min()
oderMath.max()
Sie können 6 Zeichen sparen, indem Sie dies tun:quelle
Runden
Ich weiß, dass Alternativen
Math.floor()
gepostet wurden, aber was ist mit den anderen?Bodenbelag:
Runden:
Decke:
quelle
0|x+1
einfach 1 addieren, wenn die Zahl, deren Obergrenze Sie ermitteln möchten, bereits eine Ganzzahl ist. Eine (meist) sichere Alternative ist0|x+1-1e9
, aber das ist nur drei Bytes kürzer.0|x+1-1e-9
?x%1?-~x:x
(9 Zeichen) ist eine bessere Alternative. Wie bei den Bodenbelägen0|x
und~~x
funktioniert es jedoch nur bei positiven Zahlen.In Fällen, in denen Sie den ternären Operator verwenden, um zwischen zwei Zahlen zu wählen , und die Bedingung entweder ein Boolescher Wert oder eine Zahl ist
1 or 0
, können Sie stattdessen mathematische Operationen ausführen:Hinweis: Zusätzlich zu diesem, müssen Sie den unnötigen entfernen
0-
,+0
,+-
usw.Hinweis 2: gibt es einen Einzelfall , wo
(x) !== (x?1:0)
, wiex
sein muss ,typeof === "number"
damit es funktioniert. In diesem Fall(-x)
funktioniert es jedoch einwandfrei.Hinweis 3: Wenn Sie keine Einsparungen finden, verwenden Sie einfach die erstere
(x?y:z)
Früher dachte ich, dass Methode B niemals A schlagen könnte, es gibt jedoch Ausnahmen:
Ich habe ein Github-Projekt erstellt , das uns die Vereinfachung erleichtert ( jsFiddle-Demo )
quelle
void 0
(es ist keine Funktion, sondern ein Schlüsselwort) ist kein Wert, es wird einfach zurückgegebenundefined
.a
muss jedoch entweder 1 oder 0 sein, damit es funktionierttl; dr: Nutze ES6 Features!
Pfeilfunktionen
Doc: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/arrow_functions
Beispiel:
quelle
for
...of
ist cool. Noch kürzer alsfor each
..in
.b = [s(x) for (x of a)]
.Literale missbrauchen
Das aktuelle Beispiel: Prüfen Sie, ob
"c"
Groß- oder Kleinschreibung vorliegt, egal ob kein Buchstabequelle
String({})
gibt"[object Object]"
.So vergleichen Sie eine Zahl anhand der Umwandlung von Zahlen in Boolesche Werte:
Wenn Sie überprüfen wollen , wenn etwas zu einer gleich positiven Zahl , können Sie diesen Betrag abziehen und umgekehrt , was in dem war
if
undelse
Blöcke:Und falls Sie mit einer negativen Zahl (* anders als
-1
) vergleichen möchten , müssen Sie nur diese Zahl addieren, anstatt sie zu subtrahieren.* Nun, Sie können sicherlich verwenden
x.indexOf(y) + 1
, aber in dem speziellen Fall-1
haben Sie die Möglichkeit,~x.indexOf(y)
stattdessen zu verwenden .quelle
Verwenden Sie Mozillas nicht standardmäßige Funktion zum Schließen von Ausdrücken, um viele Zeichen in einem Skript zu speichern, die nur in den SpiderMonkey / Firefox- oder Rhino-Engines funktionieren müssen. Zum Beispiel,
wird
Weitere Tricks finden Sie auf der Seite Stapelüberlauf.
quelle
->bar
let foo = () => bar;
Ironischerweise kürzer als der oben genannte Golf-Code.foo=_=>bar
noch kürzer.Verwenden Sie
if(~a.indexOf(b))
anstelle vonif(a.indexOf(b)!=-1)
quelle
Anstatt zu schreiben
true
, können Sie verwenden!0
.quelle
!1
zfalse
.1
fürtrue
und0
fürfalse
, es sei denn, Sie benötigen wirklich die wörtlichen Werte.Umwandlung in einen Booleschen Wert :
Hinweis: Dies ändert sich
0
,""
,false
,null
,undefined
undNaN
zufalse
(alles anderetrue
)quelle