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?


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

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

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

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

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

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

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 .


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.

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.


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

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.


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"

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

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;

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


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


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

2

Zapomniałem:

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

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.


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


1

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

  var $$ = document.getElementById;

  $$('samText');

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

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) 

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;

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

To wygląda niesamowicie, jaka jest techniczna nazwa tego?
TrySpace

0

int do rzutowania stringów

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

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.


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


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.