Bester Javascript syntaktischer Zucker

81

Hier sind einige Juwelen:

Literale:

var obj = {}; // Object literal, equivalent to var obj = new Object();
var arr = []; // Array literal, equivalent to var arr = new Array();
var regex = /something/; // Regular expression literal, equivalent to var regex = new RegExp('something');

Standardeinstellungen:

arg = arg || 'default'; // if arg evaluates to false, use 'default', which is the same as:
arg = !!arg ? arg : 'default';

Natürlich kennen wir anonyme Funktionen, aber es ist großartig, sie als Literale behandeln und vor Ort (als Abschluss) ausführen zu können:

(function() { ... })(); // Creates an anonymous function and executes it

Frage: Welcher andere großartige syntaktische Zucker ist in Javascript verfügbar?

Augenlidlosigkeit
quelle
2
Das war mir nicht bewusst || Standardwertsyntax. Schön und kompakt, wenn auch nicht so intuitiv. (Vielleicht habe ich es gesehen, aber nie verstanden.)
Chris Noe
1
Es fiel mir viel schwerer, die ternäre Syntax zu verstehen. Es wird wie eine zweite Natur erscheinen, nachdem Sie es ein paar Mal geschrieben haben. Soweit Sie es gesehen haben, verwenden es meiner Meinung nach sowohl jquery.js als auch prototype.js.
Augenlidlosigkeit
1
Wie wäre es, jedes der Beispiele zu erklären?
pc1oad1etter
2
Ich wusste nichts über "arg || 'default'". Ich würde erwarten, dass es einen booleschen Wert zurückgibt, aber es gibt den ersten Wert (von links) zurück, der als wahr ausgewertet wird (ähnlich wie Python)! Es ist viel besser als "arg = arg? Arg: 'default'"!
Jamol
Chris Noe hat diesen Thread verpfändet!
Mahesh Velaga

Antworten:

58

Abrufen der aktuellen Datums- und Uhrzeitangabe in Millisekunden:

Date.now()

Zum Beispiel, um die Ausführung eines Codeabschnitts zeitlich festzulegen:

var start = Date.now();
// some code
alert((Date.now() - start) + " ms elapsed");
Chris Noe
quelle
Dies ist in der Tat der beste syntaktische Javascript-Zucker. Ein winnar si yuo.
Augenlidlosigkeit
3
OrbMan, das hängt wahrscheinlich vom Kontext ab; Wenn es als Argument übergeben wird, kann es zu einem Objekt und nicht zu einer Zahl oder einem String gezwungen werden. In diesem Fall hätte das + es bereits zu einer Zahl gezwungen. Tatsächlich scheint + als Abkürzung für parseInt (Wert 10) zu fungieren.
Augenlidlosigkeit
Korrektur: Es gibt einen Unterschied zu parseInt (Wert 10). Zum Beispiel sind + [3] und parseInt ([3], 10) beide gleich der Zahl 3, aber + [3, 4] == NaN und parseInt ([3, 4], 10) == 3.
Augenlidlosigkeit
Äh ... all diese Instanzen von parseInt (Wert, 10) sollten parseFloat (Wert) sein. Und Chris Noe, Entschuldigung für den Kommentar-Spam;)
Augenlidlosigkeit
1
Meine Neugier hat mich dazu gedrängt, es in jsperf zu versuchen, und es scheint, dass das kanonischste getTime () :) (ref. Jsperf.com/millisecondsdate )
sirLisko
33

Objektmitgliedschaftstest:

var props = {a: 1, b: 2};

("a" in Requisiten) // true
("b" in Requisiten) // true
("c" in Requisiten) // false
Chris Noe
quelle
Das ist sicherlich prägnanter als Requisiten. A === undefiniert Danke.
Augenlidlosigkeit
15
Und es ist wahr, auch wenn Requisiten = {a: undefiniert}.
Ephemient
Zu Ihrer Information - Firefox löst einen TypeError aus, wenn Sie versuchen, "in" für ein XPCNativeWrapper-Objekt zu verwenden. Und ab Firefox 4 werden viele Objekte verpackt. Also zurück zu Requisiten.a === in diesen Fällen undefiniert.
Chris Noe
26

In Mozilla (und angeblich IE7) können Sie eine XML-Konstante erstellen, indem Sie:

var xml = <elem> </ elem>;

Sie können auch Variablen ersetzen:

var elem = "html";
var text = "Irgendein Text";
var xml = <{elem}> {text} </ {elem}>;
Chris Noe
quelle
"Ja wirklich?" Gibt es andere Motoren, die das unterstützen?
Augenlidlosigkeit
1
Ich frage mich nur: Was können Sie mit dieser "xml" -Variablen tun, wenn Sie sie erstellt haben? Wenn Sie jetzt in Firebug damit spielen, sieht es so aus, als hätte es keine Methoden oder Eigenschaften und Sie können es nicht zum DOM hinzufügen.
Nickf
Hilfreicher Link: developer.mozilla.org/index.php?title=En/…
Chris Noe
8
E4X-Literale sind eine Sicherheitskatastrophe aufgrund von Angriffen mit Cross-Site-Script-Inclusion und nicht merklich besser, als nur IMO "var xml = new XML ('<elem> </ elem>')" sagen zu können.
Bobince
2
@CharlieSomerville Das ist nicht das Risiko. E4X verwandelt möglicherweise "sichere" [X] [HT] ML-Dateien in aktives JS. Bitte lesen Sie code.google.com/p/doctype/wiki/ArticleE4XSecurity, um Hintergrundinformationen zu diesem Problem zu erhalten.
Bobince
26

Verwenden anonymer Funktionen und eines Abschlusses zum Erstellen einer privaten Variablen (Ausblenden von Informationen) und der zugehörigen Methoden zum Abrufen / Festlegen:

var getter, setter;

(function()
{
   var _privateVar=123;
   getter = function() { return _privateVar; };
   setter = function(v) { _privateVar = v; };
})()
Asche
quelle
Ich habe einen Moment gebraucht, aber ich habe es verstanden. Das ist ordentlich.
Matt Lohkamp
Ich habe vor einiger Zeit eine ähnliche Technik entdeckt, als ich durch die swfobject-Quelle geschaut habe. Die Verwendung von Closures zum Erstellen privater Variablen / Methoden ist etwas, woran ich wahrscheinlich nie gedacht hätte. Es ist irgendwie cool.
Herms
Mit der neuen JS-Version können wir die einfachere verwendenif(true) { let _privateVar=123; }
Kulvar
Beachten Sie hier das stilistische Problem "Hundebälle". Siehe: twitter.com/paul_irish/status/176187448420864000?lang=de
Jonathan.Brink
22

In der Lage sein, native JavaScript-Typen durch prototypische Vererbung zu erweitern.

String.prototype.isNullOrEmpty = function(input) {
    return input === null || input.length === 0;
}
steve_c
quelle
6
Vermeiden Sie dies einfach mit Array: stackoverflow.com/questions/61088/…
Chris Noe
Dies ist wahr, aber nur, wenn Sie die for (a in b) -Schleife verwenden. Normalerweise verwende ich Frameworks, wie ich sicher bin, dass es alle anderen tun. Infolgedessen verwende ich normalerweise .each ()
steve_c
Es ist ein potenzielles Problem , wenn jeder Code in Ihrem Container Verwendungen für (a in b). Und wenn dieser Container ein Browser ist, können Sie anderen Code in Ihrem Browser beschädigen (z. B. dieses Framework). Ich bin von dem einen betrogen worden.
Chris Noe
Ja. Gute Punkte, Chris. Ich zähle immer noch die prototypische Vererbung als eine der besten Funktionen von JavaScript :)
steve_c
für (var i in obj) {if (! obj.hasOwnProperty (i)) {continue; } ...}
Augenlidlosigkeit
21

Verwenden Sie ===diese Option , um Wert und Typ zu vergleichen :

var i = 0;
var s = "0";

if (i == s) // true

if (i === s) // false
Chris Noe
quelle
Es wird tatsächlich als streng gleich bezeichnet - im Grunde vermeidet es alle Typkonvertierungen, die sonst passieren müssen, wenn ==
olliej
andere Sprachen (PHP) nennen es auch "Identitätsprüfung", dh: Sind diese beiden Werte identisch ?
Nickf
@nickf, es ist ein bisschen eine Fehlbezeichnung. $var1 = 'string'; $var2 = 'string'; $var1 === $var2; // true, obwohl $var1und $var2nicht identisch sind (Verweise auf denselben gespeicherten Wert im Speicher), nur denselben Typ und denselben Wert.
Augenlidlosigkeit
@eyelidlessness, ich bin mir nicht sicher, ob Javascript so funktioniert ... Strings werden (normalerweise) gespeichert und als Wert übergeben. Objekte werden jedoch als Referenz gespeichert : var1 = {a : 'b'}; var2 = {a : 'b'}; var1 === var2 // false.
Nickf
@nickf, das verstehe ich. Sie können jedoch das Siegel im PHP-Code entfernen und das gleiche Ergebnis in JavaScript erzielen. Diese Zeichenfolgen sind nicht identisch , ihre Werte jedoch.
Augenlidlosigkeit
21

Mehrzeilige Zeichenfolgen:

var str = "Dies ist \
alle eins \
Zeichenfolge. ";

Da Sie die nachfolgenden Zeilen nicht einrücken können, ohne auch das Leerzeichen in die Zeichenfolge einzufügen, bevorzugen die Benutzer im Allgemeinen die Verkettung mit dem Plus-Operator. Dies bietet jedoch eine schöne Dokumentfunktion .

Chris Noe
quelle
2
Faire Warnung - Eine Ausnahme wird ausgelöst, wenn nach den \ 's Leerzeichen stehen.
Daniel Szabo
21

Ändern Sie die Länge eines Arrays

Die Eigenschaft length ist nicht schreibgeschützt . Sie können es verwenden, um die Größe eines Arrays zu erhöhen oder zu verringern.

var myArray = [1,2,3];
myArray.length // 3 elements.
myArray.length = 2; //Deletes the last element.
myArray.length = 20 // Adds 18 elements to the array; the elements have the empty value. A sparse array.
pramodc84
quelle
1
Sir, das muss die wichtigste Antwort auf SO sein, glaube ich. Nicht mehr pushfür mich, hehe. Vielen Dank.
Aefxx
4
Tatsächlich existieren die auf diese Weise erstellten Elemente nicht (sie haben auch nicht den undefinierten Wert, aber wenn Sie auf sie zugreifen, werden Sie undefiniert). Sie können sie auch nicht mit for..in durchlaufen.
Yorick
16

Wiederholen Sie eine Zeichenfolge wie "-" eine bestimmte Anzahl von Malen, indem Sie die Join-Methode für ein leeres Array nutzen:

var s = new Array(repeat+1).join("-");

Ergibt "---" bei Wiederholung == 3.

J c
quelle
15

Ist wie der Standardoperator ||der Guard-Operator &&.

answer = obj && obj.property

im Gegensatz zu

if (obj) {
    answer = obj.property;
}
else {
    answer = null;
}
Skilldrick
quelle
1
Das muss nicht unbedingt sein null. Dies ist nur dann der Fall, wenn obj === null.
Pimvdb
1
Kann auch in Verbindung mit || verwendet werden um eine Sicherung für den Fall sicherzustellen, dass entweder obj überhaupt nicht vorhanden ist ODER das Objekt vorhanden ist, die Schlüsseleigenschaft jedoch nicht. Auf diese Weise wird die Antwort immer definiert: answer = (obj && obj.property) || 'backupprop';
Dtipson
13
var tags = {
    name: "Jack",
    location: "USA"
};

"Name: {name}<br>From {location}".replace(/\{(.*?)\}/gim, function(all, match){
    return tags[match];
});

Rückruf zum Ersetzen von Zeichenfolgen ist nur nützlich.

Serkan Yersen
quelle
12

Getter und Setter :

function Foo(bar)
{
    this._bar = bar;
}

Foo.prototype =
{
    get bar()
    {
        return this._bar;
    },

    set bar(bar)
    {
        this._bar = bar.toUpperCase();
    }
};

Gibt uns:

>>> var myFoo = new Foo("bar");
>>> myFoo.bar
"BAR"
>>> myFoo.bar = "Baz";
>>> myFoo.bar
"BAZ"
Jonny Buchanan
quelle
Ja, es wird ein bisschen schöner sein als der aktuelle Ansatz, den ich verwendet habe.
Ash
@eyelidlessness ist es in Object.defineProperty von ECMAScript 5, das der IE implementiert und andere Browser defineGetter verwenden können .
Eli Gray
IE8 implementiert nur Getter / Setter für DOM-Objekte, daher ist es nutzlos, wenn Sie Ihre eigenen Objekt-APIs übersichtlicher gestalten: - /
Jonny Buchanan
5

Dies ist kein exklusives Javascript, sondern speichert wie drei Codezeilen:

check ? value1 : value2
Levik
quelle
Gibt es ein Äquivalent dazu, wenn kein Wert zugewiesen wird (z. B. fnName? FnName: defaultFn;)?
Augenlidlosigkeit
1
Nein, der ternäre Operator dient ausschließlich Ausdrücken. Keine Aussagen
Josh Hinman
1
Sie können damit anonyme Funktionen wie folgt auswerten: "var myFunc = (browserIsIE? function () {...}: function () {...})". Ich persönlich würde es nicht empfehlen, da es ziemlich verwirrend ist, aber zumindest ist es möglich.
Nickf
"bewerten" ist wahrscheinlich nicht das beste Wort in diesem vorherigen Kommentar. Umm .. zuweisen?
Nickf
@eyelidlessness: Ja: fnName? fnName (): defaultFn (); // auf einer Linie für sich, arbeitet
Ates Goral
4

Ein bisschen mehr zu Leviks Beispiel:

var foo = (condition) ? value1 : value2;
VirtuosiMedia
quelle
4
Sie brauchen die Klammer nicht. Ternäre Operatoren sind auch vielen anderen Sprachen gemeinsam.
Ates Goral
1
Die Klammern helfen, wenn die bedingte Anweisung syntaktische Mehrdeutigkeiten aufweist (z. B. Bestimmen, für welche Komponente der bedingten Anweisung das? Gilt).
Augenlidlosigkeit
4

Das Array # forEach in Javascript 1.6

myArray.forEach(function(element) { alert(element); });
Pablo Cabrera
quelle
4

Nach obj || {default: true} Syntax:

Rufen Sie Ihre Funktion folgendermaßen auf: hello (requiredOne && requiredTwo && needThree) Wenn ein Parameter undefiniert oder falsch ist, wird hallo (false) aufgerufen, manchmal nützlich

vvo
quelle
4

In Parsing-Situationen mit einem festen Satz von Komponenten:

var str = "John Doe";

Sie können die Ergebnisse mithilfe der Synatx "Destrukturierungszuweisung" direkt Variablen zuordnen:

var [fname, lname] = str.split(" ");
alert(lname + ", " + fname);

Welches ist ein bisschen besser lesbar als:

var a = str.split(" ");
alert(a[1] + ", " + a[0]);

Abwechselnd:

var [str, fname, lname] = str.match(/(.*) (.*)/);

Beachten Sie, dass dies eine Javascript 1.7- Funktion ist. Das sind also derzeit die Browser Mozilla 2.0+ und Chrome 6+.

Chris Noe
quelle
Ich habe dies in der Safari Javascript-Konsole versucht und es führt zu einem Analysefehler.
Augenlidlosigkeit
Snap, ich glaube, ich habe das nur in Firefox verwendet. Ich habe einen Browserkompatibilitätshinweis hinzugefügt.
Chris Noe
Es funktioniert nicht auf Chrome 6. Es gibt SyntaxError: Unexpected token [.
RaYell
Eine kleine Untersuchung zeigt, dass Chrom 1.7 nicht ganz Standard ist. Es gibt angeblich auch ein Problem mit let: stackoverflow.com/questions/300185/…
Chris Noe
Unter Chrome 13 funktioniert es immer noch nicht. Gibt es einen Hinweis darauf, wann dies implementiert wird?
Pimvdb
3

Sofort aufgerufene Pfeilfunktion:

var test = "hello, world!";
(() => test)(); //returns "hello, world!";
Gerard Simpson
quelle
2

Ich habe vergessen:

(function() { ... }).someMethod(); // Functions as objects
Augenlidlosigkeit
quelle
2

Erstellen Sie ein anonymes Objektliteral mit einfach: ({})

Beispiel: Sie müssen wissen, ob Objekte die valueOf-Methode haben:

var hasValueOf = !! ({}). valueOf

Syntaktischer Bonuszucker: das Doppel-Nicht '!!' für die Umwandlung so ziemlich alles in einen Booleschen sehr prägnant.

mkoistinen
quelle
1

Ich liebe es, einen JSON-String auswerten () und eine vollständig aufgefüllte Datenstruktur zurückerhalten zu können. Ich hasse es, alles mindestens zweimal schreiben zu müssen (einmal für IE, wieder für Mozilla).

Dicroce
quelle
1

Zuweisen der häufig verwendeten Schlüsselwörter (oder beliebiger Methoden) zu einfachen Variablen wie ths

  var $$ = document.getElementById;

  $$('samText');
RameshVel
quelle
3
Das funktioniert nicht (zumindest in Chrome), da der thisWert verloren geht. Stattdessen sollten Sie verwenden document.getElementById.bind(document). Ohne bindes wird lediglich die HTMLDocument.prototype.getElementByIdFunktion zugewiesen , ohne die Information, dass sie aufgerufen werden soll document.
Pimvdb
1

Die Date-Klasse von JavaScript bietet ein Semi "Fluent Interface". Dies gleicht aus, dass der Datumsanteil nicht direkt aus einer Datumsklasse extrahiert werden kann:

var today = new Date((new Date()).setHours(0, 0, 0, 0));

Es ist keine vollständig fließende Schnittstelle, da im Folgenden nur ein numerischer Wert angegeben wird, der eigentlich kein Datumsobjekt ist:

var today = new Date().setHours(0, 0, 0, 0);
palswim
quelle
1

Standard-Fallback:

var foo = {}; // empty object literal

alert(foo.bar) // will alert "undefined"

alert(foo.bar || "bar"); // will alert the fallback ("bar")

Ein praktisches Beispiel:

// will result in a type error
if (foo.bar.length === 0)

// with a default fallback you are always sure that the length
// property will be available.
if ((foo.bar || "").length === 0) 
Roosteronsäure
quelle
1

Hier ist eine, die ich gerade entdeckt habe: Nullprüfung vor dem Aufruf der Funktion:

a = b && b.length;

Dies ist ein kürzeres Äquivalent zu:

a = b ? b.length : null;

Das Beste daran ist, dass Sie eine Immobilienkette überprüfen können:

a = b && b.c && b.c.length;
Lightblade
quelle
1

Ich finde es toll, wie einfach es ist, mit Listen zu arbeiten:

var numberName = ["zero", "one", "two", "three", "four"][number];

Und Hashes:

var numberValue = {"zero":0, "one":1, "two":2, "three":3, "four":4}[numberName];

In den meisten anderen Sprachen wäre dies ziemlich schwerer Code. Wertvorgaben sind auch sehr schön. Zum Beispiel Fehlercode-Berichterstattung:

var errorDesc = {301: "Moved Permanently",
                 404: "Resource not found",
                 503: "Server down"
                }[errorNo] || "An unknown error has occurred";
Manixrock
quelle
Das sieht toll aus, wie lautet der technische Name dafür?
TrySpace
0

int to string cast

var i = 12;
var s = i+"";
Martijn Laarman
quelle
3
Dies sieht für mich nicht "zuckerhaltiger" aus als ein Straight i.toString () oder String (i). Kurz! = Zucker.
Ates Goral
0
element.innerHTML = "";  // Replaces body of HTML element with an empty string.

Eine Verknüpfung zum Löschen aller untergeordneten Knoten eines Elements.

pramodc84
quelle
6
Das ist nicht wirklich Javascript, es ist DOM, und es ist derzeit nicht Standard.
Augenlidlosigkeit
0

Konvertieren Sie eine Zeichenfolge in eine Ganzzahl, die standardmäßig auf 0 gesetzt ist, falls dies nicht möglich ist.

0 | "3" //result = 3
0 | "some string" -> //result = 0
0 | "0" -> 0 //result = 0

Kann in einigen Fällen nützlich sein, meistens wenn 0 als schlechtes Ergebnis angesehen wird

Raimonds
quelle
0

Vorlagenliterale

var a = 10;
var b = 20;
var text = `${a} + ${b} = ${a+b}`;

dann wird die Textvariable wie folgt sein!

10 + 20 = 30

Mohan Kumar
quelle