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?


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");

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

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}>;

"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


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; };
})()

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;
}

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

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 .


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.

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.


15

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

answer = obj && obj.property

im Gegensatz zu

if (obj) {
    answer = obj.property;
}
else {
    answer = null;
}

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.


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"

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

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;

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

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


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+.


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!";


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.


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).


1

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

  var $$ = document.getElementById;

  $$('samText');

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);

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) 

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;

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";

Das sieht toll aus, wie lautet der technische Name dafür?
TrySpace

0

int to string cast

var i = 12;
var s = i+"";

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.


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


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.