Najlepszy cukier składniowy javascript

81

Oto kilka perełek:

Literały:

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

Wartości domyślne:

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

Oczywiście znamy funkcje anonimowe, ale możliwość traktowania ich jako literałów i wykonywania ich na miejscu (jako zamknięcie) jest świetna:

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

Pytanie: Jaki inny wspaniały cukier składniowy jest dostępny w javascript?

powiek
źródło
2
Nie byłem tego świadomy || domyślna składnia wartości. Ładny i kompaktowy, choć nie tak intuicyjny. (Może nie widać go, ale nigdy go nie zrozumiał.)
Chris Noe
1
O wiele trudniej mi było uchwycić trójskładnikową składnię. Po kilkukrotnym napisaniu będzie to wyglądało na drugą naturę. Jeśli chodzi o miejsca, w których mogłeś to zobaczyć, myślę, że używają go zarówno jquery.js, jak i prototype.js.
powiek
1
Co powiesz na wyjaśnienie każdego z przykładów?
pc1oad1etter
2
Nie wiedziałem o "arg || 'default'". Spodziewałbym się, że zwróci wartość logiczną, ale zwraca pierwszą wartość (od lewej), której wynikiem jest prawda (podobnie jak w Pythonie)! Jest dużo lepsze niż "arg = arg? Arg: 'default'"!
Jamol
Chris Noe zastawił ten wątek!
Mahesh Velaga

Odpowiedzi:

58

Pobieranie aktualnej daty i godziny w milisekundach:

Date.now()

Na przykład, aby określić czas wykonania sekcji kodu:

var start = Date.now();
// some code
alert((Date.now() - start) + " ms elapsed");
Chris Noe
źródło
W rzeczywistości jest to najlepszy cukier składniowy javascript. A winnar si yuo.
powiek
3
OrbMan, to prawdopodobnie zależy od kontekstu; jeśli przekazujesz go jako argument, może być wymuszony na Object, a nie na Number lub String, w którym to przypadku + wymusiłby już to na Number. W rzeczywistości + wydaje się działać jako skrót dla parseInt (value, 10).
powiek
Korekta: ma pewną różnicę w stosunku do parseInt (wartość, 10). Na przykład + [3] i parseInt ([3], 10) są równe liczbie 3, ale + [3, 4] == NaN i parseInt ([3, 4], 10) == 3.
bez powiek
Er ... wszystkie te wystąpienia parseInt (wartość, 10) powinny być parseFloat (wartość). I Chris Noe, przepraszam za spam w komentarzach;)
powiek.
1
Ciekawość popchnęła mnie do wypróbowania tego w jsperf i wydaje się, że najbardziej wydajna jest kanoniczna getTime () :) (ref. Jsperf.com/millisecondsdate )
sirLisko
33

Test członkostwa obiektu:

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

(„a” we właściwościach) // prawda
(„b” we właściwościach) // prawda
(„c” we właściwościach) // false
Chris Noe
źródło
Jest to z pewnością bardziej zwięzłe niż props.a === undefined Dzięki.
powiek
15
I to prawda, nawet jeśli props = {a: undefined}.
ephemient
FYI - Firefox generuje błąd TypeError podczas próby użycia „in” na obiekcie XPCNativeWrapper. Począwszy od Firefoksa 4, wiele obiektów jest opakowanych. Wracamy więc do props.a === undefined w tych przypadkach.
Chris Noe,
26

W Mozilli (i podobno IE7) możesz stworzyć stałą XML używając:

var xml = <elem> </elem>;

Możesz również podstawiać zmienne:

var elem = "html";
var text = "Jakiś tekst";
var xml = <{elem}> {text} </ {elem}>;
Chris Noe
źródło
Naprawdę? Czy są inne silniki, które to obsługują?
powiek,
1
Zastanawiam się tylko: co możesz zrobić ze zmienną „xml” po jej utworzeniu? Po prostu bawię się nim teraz w firebug, wygląda na to, że nie ma żadnych metod ani właściwości i nie można go dodać do DOM.
nickf
8
Literały E4X to katastrofa bezpieczeństwa spowodowana atakami z włączaniem skryptów między lokacjami i naprawdę niezauważalnie lepsza niż zwykła możliwość powiedzenia IMO „var xml = new XML ('<elem> </elem>')”.
bobince
2
@CharlieSomerville To nie jest ryzyko. E4X potencjalnie zamienia „bezpieczne” pliki [X] [HT] ML w aktywny JS. Zapoznaj się z code.google.com/p/doctype/wiki/ArticleE4XSecurity, aby zapoznać się z podstawowymi informacjami na temat tego problemu.
bobince
26

Korzystanie z funkcji anonimowych i domknięcia do tworzenia zmiennej prywatnej (ukrywanie informacji) i powiązanych metod get / set:

var getter, setter;

(function()
{
   var _privateVar=123;
   getter = function() { return _privateVar; };
   setter = function(v) { _privateVar = v; };
})()
Popiół
źródło
zajęło mi to chwilę, ale rozumiem. to jest fajne.
Matt Lohkamp
Podobną technikę odkryłem jakiś czas temu, przeglądając źródło swfobject. Używanie domknięć do tworzenia prywatnych zmiennych / metod jest czymś, o czym prawdopodobnie nigdy bym nie pomyślał. To całkiem fajne.
Herms
Dzięki nowej wersji JS możemy skorzystać z prostszego if(true) { let _privateVar=123; }
Kulvar
Należy pamiętać o potencjalnym problemie stylistycznym „psich piłek”. Zobacz: twitter.com/paul_irish/status/176187448420864000?lang=en
Jonathan.Brink
22

Możliwość rozszerzania natywnych typów JavaScript poprzez dziedziczenie prototypowe.

String.prototype.isNullOrEmpty = function(input) {
    return input === null || input.length === 0;
}
steve_c
źródło
6
Po prostu unikaj robienia tego w Array: stackoverflow.com/questions/61088/ ...
Chris Noe
To prawda, ale tylko wtedy, gdy używasz pętli for (a in b). Zwykle używam frameworków, tak jak na pewno wszyscy. W konsekwencji zazwyczaj używam
.each
Jest to potencjalny problem, jeśli jakikolwiek kod w twoim kontenerze używa (a in b). A kiedy tym kontenerem jest przeglądarka, możesz łamać inny kod w swojej przeglądarce (np. Ten framework). Zostałem oszukany przez jednego.
Chris Noe,
Tak. Dobre punkty, Chris. Nadal uważam dziedziczenie prototypów za jedną z najlepszych cech JavaScript :)
steve_c
for (var i in obj) {if (! obj.hasOwnProperty (i)) {kontynuuj; } ...}
powiek
21

Użyj ===do porównania wartości i wpisz:

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

if (i == s) // prawda

if (i === s) // fałsz
Chris Noe
źródło
W rzeczywistości jest to określane jako ścisłe równe - w zasadzie unika wszystkich konwersji typów, które w przeciwnym razie musiałyby mieć miejsce podczas robienia ==
olliej
inne języki (PHP) również nazywają to sprawdzaniem tożsamości, tj .: czy te dwie wartości są identyczne ?
nickf
@nickf, to trochę myląca nazwa. $var1 = 'string'; $var2 = 'string'; $var1 === $var2; // true, chociaż $var1i $var2nie są identyczne (odniesienia do tej samej wartości przechowywanej w pamięci), tylko tego samego typu i tej samej wartości.
powiek
@eyelidlessness, nie jestem pewien, czy javascript działa w ten sposób ... ciągi są (zwykle) przechowywane i przekazywane przez wartość. Jednakże obiekty są przechowywane jako odniesienie: var1 = {a : 'b'}; var2 = {a : 'b'}; var1 === var2 // false.
nickf
@nickf, rozumiem to. Ale możesz usunąć sigil w kodzie PHP i uzyskać ten sam wynik w JavaScript. Te ciągi nie są identyczne , ale ich wartości są.
powiek
21

Ciągi wieloliniowe:

var str = "To jest \
wszystko jedno \
strunowy.";

Ponieważ nie można wciskać kolejnych wierszy bez dodawania białych znaków do łańcucha, ludzie zazwyczaj wolą łączyć z operatorem plus. Ale to zapewnia przyjemną możliwość tworzenia dokumentów .

Chris Noe
źródło
2
Uczciwe ostrzeżenie - wyjątek zostanie zgłoszony, jeśli po znaku \ 'znajdują się spacje końcowe.
Daniel Szabo
21

Zmień rozmiar tablicy

length nie jest tylko do odczytu . Możesz go użyć do zwiększenia lub zmniejszenia rozmiaru tablicy.

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
źródło
1
Sir, to chyba najważniejsza odpowiedź na SO, jak sądzę. Nigdy więcej pushdla mnie, hehe. Wielkie dzięki.
aefxx
4
w rzeczywistości utworzone w ten sposób elementy tak naprawdę nie istnieją (nie mają też niezdefiniowanej wartości, ale dostęp do nich spowoduje niezdefiniowanie). Nie możesz też ich iterować za pomocą for..in.
yorick
16

Powtarzanie ciągu, takiego jak „-”, określoną liczbę razy, wykorzystując metodę join w przypadku pustej tablicy:

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

Wyniki w postaci „---”, gdy powtórz == 3.

J c
źródło
15

Podobnie jak w przypadku operatora domyślnym ||jest operatorem strażnik &&.

answer = obj && obj.property

w przeciwieństwie do

if (obj) {
    answer = obj.property;
}
else {
    answer = null;
}
Skilldrick
źródło
1
Nie musi tak być null. Dzieje się tak tylko wtedy, gdy obj === null.
pimvdb
1
Może być również używany w połączeniu z || w celu zapewnienia kopii zapasowej w przypadku, gdy albo obj w ogóle nie istnieje LUB obiekt istnieje, ale właściwość klucza nie istnieje. W ten sposób odpowiedź jest zawsze definiowana: 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];
});

wywołanie zwrotne do zamiany napisów jest po prostu przydatne.

Serkan Yersen
źródło
12

Programy pobierające i ustawiające :

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

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

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

Daje nam:

>>> var myFoo = new Foo("bar");
>>> myFoo.bar
"BAR"
>>> myFoo.bar = "Baz";
>>> myFoo.bar
"BAZ"
Jonny Buchanan
źródło
Tak, będzie trochę ładniej niż moje obecne podejście.
Ash
@eyelidlessness znajduje się w Object.defineProperty ECMAScript 5, który implementuje IE, a inne przeglądarki mogą używać defineGetter .
Eli Gray
IE8 implementuje tylko metody pobierające / ustawiające obiekty DOM, więc jest bezużyteczne, jeśli chodzi o tworzenie własnych interfejsów API obiektów: - /
Jonny Buchanan
5

To nie jest wyłączne dla javascript, ale zapisuje jak trzy linie kodu:

check ? value1 : value2
levik
źródło
Czy istnieje odpowiednik tego, gdy nie przypisujesz wartości (np. FnName? FnName: defaultFn;)?
powiek,
1
Nie, operator trójskładnikowy służy wyłącznie do wyrażeń; brak wypowiedzi
Josh Hinman
1
możesz go użyć do oceny funkcji anonimowych, takich jak ta: "var myFunc = (browserIsIE? function () {...}: function () {...})". osobiście nie polecałbym tego, ponieważ jest to dość zagmatwane, ale przynajmniej jest to możliwe.
nickf
„oceniać” prawdopodobnie nie jest najlepszym słowem w tym poprzednim komentarzu. Umm .. przypisać?
nickf
@eyelidlessness: Yes: fnName? fnName (): defaultFn (); // na własnej linii, działa
Ates Goral
4

Trochę więcej na przykładzie Levika:

var foo = (condition) ? value1 : value2;
VirtuosiMedia
źródło
4
Nie potrzebujesz nawiasów. Operatory trójskładnikowe są również wspólne dla wielu innych języków.
Ates Goral
1
Nawiasy pomagają, gdy występuje niejednoznaczność składniowa w instrukcji warunkowej (np. Określenie, do którego składnika instrukcji warunkowej?).
powiek
4

Po obj || Składnia {domyślna: prawda}:

wywołując swoją funkcję w ten sposób: hello (requiredOne && requiredTwo && needThree) jeśli jeden parametr jest niezdefiniowany lub fałszywy, wywoła hello (false), czasami przydatne

vvo
źródło
4

W sytuacjach analizowania ze stałym zestawem części składowych:

var str = "John Doe";

Możesz przypisać wyniki bezpośrednio do zmiennych, używając synatx "przypisania destrukturyzacji":

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

Co jest nieco bardziej czytelne niż:

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

Na przemian:

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

Zauważ, że jest to funkcja Javascript 1.7 . W tej chwili są to przeglądarki Mozilla 2.0+ i Chrome 6+.

Chris Noe
źródło
Wypróbowałem to w konsoli Safari Javascript i powoduje to błąd analizy.
powiek
Snap, chyba używałem tego tylko w Firefoksie. Dodałem informację o kompatybilności przeglądarki.
Chris Noe
To nie działa w Chrome 6. Daje SyntaxError: Unexpected token [.
RaYell,
Trochę badań zaczyna ujawniać, że wersja 1.7 Chrome nie jest całkowicie standardowa. Podobno jest też problem z let: stackoverflow.com/questions/300185/…
Chris Noe
Nadal nie działa w Chrome 13. Masz jakąś wskazówkę, kiedy to zostanie wdrożone?
pimvdb
3

Funkcja natychmiastowego wywołania strzałki:

var test = "hello, world!";
(() => test)(); //returns "hello, world!";
Gerard Simpson
źródło
2

Zapomniałem:

(function() { ... }).someMethod(); // Functions as objects
powiek
źródło
2

Utwórz anonimowy literał obiektu za pomocą prostego: ({})

Przykład: musisz wiedzieć, czy obiekty mają metodę valueOf:

var hasValueOf = !! ({}). valueOf

Dodatkowy cukier syntaktyczny: podwójne nie „!!” za bardzo zwięzłe przekształcenie prawie wszystkiego w Boolean.

mkoistinen
źródło
1

Uwielbiam móc eval () string JSON i odzyskać w pełni wypełnioną strukturę danych. Nienawidzę pisać wszystkiego co najmniej dwa razy (raz dla IE, znowu dla Mozilli).

dicroce
źródło
1

Przypisywanie często używanych słów kluczowych (lub dowolnych metod) do prostych zmiennych, takich jak ths

  var $$ = document.getElementById;

  $$('samText');
RameshVel
źródło
3
To nie zadziała (przynajmniej w Chrome), ponieważ thisutracono wartość. Zamiast tego powinieneś użyć document.getElementById.bind(document). Bez bindtego jest po prostu przypisaniem HTMLDocument.prototype.getElementByIdfunkcji, bez informacji, że należy ją wywołać document.
pimvdb
1

Klasa Date w JavaScript zapewniająca półpłynny interfejs. To rekompensuje brak możliwości bezpośredniego wyodrębnienia części daty z klasy Date:

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

Nie jest to w pełni płynny interfejs, ponieważ poniższe informacje dają nam tylko wartość liczbową, która w rzeczywistości nie jest obiektem Date:

var today = new Date().setHours(0, 0, 0, 0);
palswim
źródło
1

Domyślna kreacja zastępcza:

var foo = {}; // empty object literal

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

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

Praktyczny przykład:

// 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) 
roosteronacid
źródło
1

Oto jeden, który właśnie odkryłem: zerowe sprawdzenie przed wywołaniem funkcji:

a = b && b.length;

To jest krótszy odpowiednik:

a = b ? b.length : null;

Najlepsze jest to, że możesz sprawdzić łańcuch nieruchomości:

a = b && b.c && b.c.length;
lightblade
źródło
1

Uwielbiam to, jak łatwo jest pracować z listami:

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

I skróty:

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

W większości innych języków byłby to dość ciężki kod. Wartości domyślne są również piękne. Na przykład raportowanie kodów błędów:

var errorDesc = {301: "Moved Permanently",
                 404: "Resource not found",
                 503: "Server down"
                }[errorNo] || "An unknown error has occurred";
manixrock
źródło
To wygląda niesamowicie, jaka jest techniczna nazwa tego?
TrySpace
0

int do rzutowania stringów

var i = 12;
var s = i+"";
Martijn Laarman
źródło
3
Nie wygląda to dla mnie bardziej „słodko” niż wykonanie prostej i.toString () lub String (i). Krótki! = Cukier.
Ates Goral
0
element.innerHTML = "";  // Replaces body of HTML element with an empty string.

Skrót do usuwania wszystkich węzłów potomnych elementu.

pramodc84
źródło
6
To nie jest tak naprawdę Javascript, to DOM i obecnie jest niestandardowy.
powiek
0

Konwertuj ciąg na liczbę całkowitą, domyślnie 0 jeśli jest to niemożliwe,

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

Może być przydatne w niektórych przypadkach, głównie wtedy, gdy 0 jest uważane za zły wynik

Raimonds
źródło
0

Literały szablonów

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

a później zmienna tekstowa będzie taka jak poniżej!

10 + 20 = 30

Mohana Kumara
źródło