En iyi javascript sözdizimsel şeker


81

İşte bazı mücevherler:

Değişmezler:

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

Varsayılanlar:

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

Elbette anonim işlevleri biliyoruz, ancak bunları değişmez değerler olarak ele alıp yerinde (bir kapanış olarak) çalıştırabilmek harika:

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

Soru: Javascript'te başka hangi harika sözdizimsel şeker var?


2
Bunun farkında değildim || varsayılan değer sözdizimi. Çok sezgisel olmasa da hoş ve kompakt. (Belki gelmiş görmüş, ama bunu hiç anlayamadım.)
Chris Noe

1
Üçlü sözdizimini anlamakta çok daha zorlandım. Birkaç kez yazdıktan sonra ikinci doğa gibi görünecek. Gördüğünüz yerlere gelince, hem jquery.js hem de prototype.js'nin kullandığını düşünüyorum.
gözkapağı kaybı

1
Örneklerin her birini açıklamaya ne dersiniz?
pc1oad1etter

2
"Arg || 'default" "hakkında bir şey bilmiyordum. Bir boole değeri döndürmesini beklerdim, ancak doğru olarak değerlendirilen (python'a benzer) ilk değeri (soldan) döndürür! "Arg = arg? Arg: 'default" "den çok daha iyi!
Jamol

Chris Noe bu konuyu rehin aldı!
Mahesh Velaga

Yanıtlar:


58

Geçerli tarih saatini milisaniye olarak alma:

Date.now()

Örneğin, bir kod bölümünün yürütülmesini zamanlamak için:

var start = Date.now();
// some code
alert((Date.now() - start) + " ms elapsed");

Aslında bu, en iyi javascript sözdizimsel şekeridir. Bir winnar si yuo.
gözkapaksızlık

3
OrbMan, bu muhtemelen içeriğe bağlıdır; bir argüman olarak iletiliyorsa, bir Sayı veya Dize yerine bir Nesneye zorlanabilir, bu durumda + bunu zaten bir Sayıya zorlamış olurdu. Aslında +, parseInt (değer, 10) için bir kısaltma işlevi görüyor gibi görünüyor.
göz kapaksızlık

Düzeltme: parseInt (değer, 10) 'dan biraz farklıdır. Örneğin, + [3] ve parseInt ([3], 10), 3 sayısına eşittir, ancak + [3, 4] == NaN ve parseInt ([3, 4], 10) == 3.
eyelidlessness

Er ... tüm bu parseInt (değer, 10) örnekleri parseFloat (değer) olmalıdır. Ve Chris Noe, spam yorumları için özür dilerim;)
eyelidlessness

1
Merakım onu ​​jsperf'te denemeye itti ve görünüşe göre en iyi performans kanonik getTime () :) (ref. Jsperf.com/millisecondsdate )
sirLisko

33

Nesne üyelik testi:

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

("a" sahne içinde) // doğru
(props'ta "b") // doğru
(props'ta "c") // yanlış

Bu kesinlikle props.a === undefined Teşekkürler.
eyelidlessness

15
Ve props = {a: undefined} olsa bile doğrudur.
ephemient

Bilginize - Firefox, bir XPCNativeWrapper nesnesinde "in" kullanmaya çalıştığınızda bir TypeError atar. Ve Firefox 4 ile başlayarak, birçok nesne paketlenmiş durumda. Öyleyse, bu durumlarda props.a === undefined'a geri dönelim.
Chris Noe

26

Mozilla'da (ve bildirildiğine göre IE7'de) aşağıdakileri kullanarak bir XML sabiti oluşturabilirsiniz:

var xml = <elem> </elem>;

Değişkenleri de değiştirebilirsiniz:

var elem = "html";
var text = "Bazı metinler";
var xml = <{elem}> {metin} </ {elem}>;

Gerçekten mi? Bunu destekleyen başka motorlar var mı?
göz kapaksızlığı

1
Merak ediyorum: "xml" değişkenini bir kez oluşturduktan sonra ne yapabilirsiniz? Şimdi onunla sadece firebug'da oynuyorum, herhangi bir metodu veya özelliği yokmuş gibi görünüyor ve bunu DOM'a ekleyemezsiniz.
nickf


8
E4X değişmez değerleri, siteler arası komut dosyası içerme saldırıları nedeniyle bir güvenlik felaketidir ve "var xml = new XML ('<elem> </elem>')" IMO diyebilmekten gerçekten fark edilir derecede daha iyi değildir.
bobince

2
@CharlieSomerville Bu risk değil. E4X, "güvenli" [X] [HT] ML dosyalarını etkin JS'ye dönüştürebilir. Bu konuyla ilgili arka plan için lütfen code.google.com/p/doctype/wiki/ArticleE4XSecurity'i okuyun .
bobince

26

Özel bir değişken (bilgi gizleme) ve ilişkili get / set yöntemlerini oluşturmak için anonim işlevler ve bir kapatma kullanma

var getter, setter;

(function()
{
   var _privateVar=123;
   getter = function() { return _privateVar; };
   setter = function(v) { _privateVar = v; };
})()

bir anımı aldı ama anladım. bu harika.
matt lohkamp

Bir süre önce swfobject kaynağına bakarken benzer bir teknik keşfettim. Özel değişkenler / yöntemler oluşturmak için kapanışları kullanmak, muhtemelen aklıma gelmeyen bir şeydi. Biraz havalı.
Herms

Yeni JS sürümü ile daha basit if(true) { let _privateVar=123; }
olanı

Buradaki "köpek topları" biçimsel potansiyel sorununun farkında olun. Bakınız: twitter.com/paul_irish/status/176187448420864000?lang=en
Jonathan.Brink

22

Prototip kalıtım yoluyla yerel JavaScript türlerini genişletebilme.

String.prototype.isNullOrEmpty = function(input) {
    return input === null || input.length === 0;
}

6
Bunu Array'e yapmaktan kaçının: stackoverflow.com/questions/61088/…
Chris Noe

Bu doğrudur, ancak yalnızca for (a in b) döngüsünü kullanırsanız. Herkesin kullandığından emin olduğum gibi, genellikle çerçeveler kullanırım. Sonuç olarak, genellikle .each () kullanıyorum
steve_c

Konteynırınızdaki herhangi bir kod (a in b) için kullanıyorsa, bu potansiyel bir sorundur . Ve bu kapsayıcı bir tarayıcı olduğunda, tarayıcınızdaki diğer kodu kırıyor olabilirsiniz (örneğin, o çerçeve). Biri tarafından çıldırıldım.
Chris Noe

Evet. İyi puan, Chris. Hala prototip kalıtımını JavaScript'in en iyi özelliklerinden biri olarak
görüyorum

for (obj içinde var) {if (! obj.hasOwnProperty (i)) {devam; } ...}
eyelidlessness

21

===Değer ve türü karşılaştırmak için kullanın :

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

eğer (i == s) // doğru

eğer (i === s) // yanlış

Aslında buna katı eşitlik denir - temelde, ==
olliej

diğer diller (PHP) de buna "kimlik" denetimi denir, yani: bu iki değer aynı mı?
nickf

@nickf, bu biraz yanlış bir adlandırma. $var1 = 'string'; $var2 = 'string'; $var1 === $var2; // trueDahi olsa $var1ve $var2aynı (bellekte aynı depolanmış değere referanslar), sadece aynı tip ve aynı değer değildir.
göz kapaksızlık

@eyelidlessness, javascript'in bu şekilde çalıştığından emin değilim ... dizeler (genellikle) değerlere göre saklanır ve aktarılır. Nesneler, ancak bir referans olarak saklanır: var1 = {a : 'b'}; var2 = {a : 'b'}; var1 === var2 // false.
nickf

@nickf, bunu anlıyorum. Ancak PHP kodundaki işareti kaldırabilir ve JavaScript'te aynı sonucu alabilirsiniz. Bunlar dize olmayan özdeş ama onların değerlerdir.
göz kapaksızlık

21

Çok satırlı dizeler:

var str = "Bu \
hepsi bir \
string. ";

Dizeye boşluk eklemeden sonraki satırları girintileyemeyeceğiniz için, insanlar genellikle artı operatörüyle bitiştirmeyi tercih ederler. Ancak bu, burada güzel bir belge özelliği sağlar.


2
Adil uyarı - \ 'lardan sonra herhangi bir boşluk varsa bir istisna atılır.
Daniel Szabo

21

Bir Dizinin Uzunluğunu Yeniden Boyutlandırma

length özelliği salt okunur değildir . Bir dizinin boyutunu artırmak veya azaltmak için kullanabilirsiniz.

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
Efendim, inanıyorum ki bu SO hakkındaki tek ve en önemli cevap olmalı. Artık pushbenim için değil, hehe. Çok teşekkürler.
aefxx

4
aslında, bu şekilde oluşturulan öğeler gerçekte mevcut değildir (onlar da tanımlanmamış değere sahip değillerdir, ancak bunlara erişmek sizi tanımsız hale getirecektir). Ayrıca for..in ile bunları yineleyemezsiniz.
yorick

16

Boş bir dizide birleştirme yönteminden yararlanarak "-" gibi bir dizeyi belirli sayıda tekrarlamak:

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

Tekrar == 3 olduğunda "---" ile sonuçlanır.


15

Varsayılan operatör gibi ||, koruma operatörüdür &&.

answer = obj && obj.property

aksine

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

1
Mutlaka olması gerekmez null. Bu sadece ne zaman geçerlidir obj === null.
pimvdb

1
|| ile birlikte de kullanılabilir nesnelerin hiç mevcut olmaması VEYA nesnenin var olması ancak key özelliğinin olmaması durumunda yedeklemeyi sağlamak için. Bu şekilde yanıt her zaman tanımlanır: 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];
});

dizge değiştirme için geri arama sadece yararlıdır.


12

Getiriciler ve ayarlayıcılar :

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

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

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

Bize verir:

>>> var myFoo = new Foo("bar");
>>> myFoo.bar
"BAR"
>>> myFoo.bar = "Baz";
>>> myFoo.bar
"BAZ"

Evet, şu an kullandığım yaklaşımdan biraz daha güzel olacak.
Ash

@eyelidlessness IE'nin uyguladığı ve diğer tarayıcıların defineGetter kullanabildiği ECMAScript 5'in Object.defineProperty'sindedir .
Eli Grey

IE8 yalnızca DOM nesneleri için alıcılar / ayarlayıcılar uygular, bu nedenle kendi nesne API'lerinizi daha temiz yapmak söz konusu olduğunda işe yaramaz: - /
Jonny Buchanan

5

Bu, javascript'e özel değildir, ancak üç satır kod gibi kaydeder:

check ? value1 : value2

Bir değer atanmadığında bunun bir eşdeğeri var mı (örn. FnName? FnName: defaultFn;)?
gözkapaksızlık

1
Hayır, üçlü operatör kesinlikle ifadeler içindir; açıklama yok
Josh Hinman

1
anonim işlevleri değerlendirmek için kullanabilirsiniz, örneğin: "var myFunc = (browserIsIE? function () {...}: function () {...})". Şahsen, oldukça kafa karıştırıcı olduğu için tavsiye etmem ama en azından mümkün.
nickf

"değerlendirmek" muhtemelen önceki yorumdaki en iyi kelime değil. Umm .. atamak?
nickf

@eyelidlessness: Evet: fnName? fnName (): defaultFn (); // kendi başına bir hatta çalışıyor
Ateş Goral

4

Levik örneğinden biraz daha fazlası:

var foo = (condition) ? value1 : value2;

4
Paranteze ihtiyacınız yok. Üçlü operatörler ayrıca diğer birçok dilde ortaktır.
Ateş Goral

1
Parantezler, koşullu ifadede sözdizimsel belirsizlik olduğunda yardımcı olur (örneğin, koşullu ifadenin hangi bileşenine uygulandığını belirleme).
göz kapaksızlık


4

Obj || {varsayılan: doğru} sözdizimi:

işlevinizi şununla çağırmak: merhaba (requiredOne && requiredTwo && needThree) Bir parametre tanımsız veya yanlışsa, merhaba (yanlış), bazen yararlı


4

Sabit bir bileşen parça setiyle durumları ayrıştırmada:

var str = "John Doe";

"Yıkıcı atama" sözdizimini kullanarak sonuçları doğrudan değişkenlere atayabilirsiniz:

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

Hangisi biraz daha okunaklı:

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

Alternatif olarak:

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

Bunun bir Javascript 1.7 özelliği olduğunu unutmayın. Bu, şu anda Mozilla 2.0+ ve Chrome 6+ tarayıcıları.


Bunu Safari Javascript konsolunda denedim ve bir ayrıştırma hatasıyla sonuçlandı.
eyelidlessness

Snap, sanırım bunu sadece Firefox'ta kullandım. Bir tarayıcı uyumluluk notu ekledim.
Chris Noe

Chrome 6'da çalışmıyor. Veriyor SyntaxError: Unexpected token [.
RaYell

Küçük bir araştırma, Chrome'un 1.7'sinin tamamen standart olmadığını ortaya çıkarmaya başlar. Bildirildiğine göre let ile ilgili de bir sorun var: stackoverflow.com/questions/300185/…
Chris Noe

Hala Chrome 13'te çalışmıyor. Bunun ne zaman uygulanacağına dair bir ipucu var mı?
pimvdb

3

Anında Çağrılan Ok işlevi:

var test = "hello, world!";
(() => test)(); //returns "hello, world!";


2

Basitçe şununla anonim bir nesne oluşturun: ({})

Örnek: nesnelerin valueOf yöntemine sahip olup olmadığını bilmeniz gerekir:

var hasValueOf = !! ({}). valueOf

Bonus sözdizimsel şeker: çift değil '!!' hemen hemen her şeyi bir Boolean'a çok kısa bir şekilde dönüştürmek için.


1

Bir json dizesini değerlendirmeyi () ve tam olarak doldurulmuş bir veri yapısını geri almayı seviyorum. Her şeyi en az iki kez yazmaktan nefret ediyorum (bir kez IE için, bir kez de Mozilla için).


1

Sık kullanılan anahtar kelimeleri (veya herhangi bir yöntemi) bu gibi basit değişkenlere atama

  var $$ = document.getElementById;

  $$('samText');

3
thisDeğer kaybolduğu için (en azından Chrome'da) işe yaramaz . Bunun yerine kullanmalısınız document.getElementById.bind(document). O olmadan, çağrılması gereken bilgi olmadan bindyalnızca HTMLDocument.prototype.getElementByIdişlevi atamaktır document.
pimvdb

1

JavaScript'in Date sınıfı yarı "Akıcı Arayüz" sağlar. Bu, tarih bölümünün doğrudan bir Date sınıfından çıkarılamaması anlamına gelir:

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

Tamamen Akıcı bir Arayüz değildir, çünkü aşağıdakiler bize yalnızca gerçekte bir Date nesnesi olmayan sayısal bir değer verecektir:

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

1

Varsayılan yedek:

var foo = {}; // empty object literal

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

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

Pratik bir örnek:

// 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

İşte yeni keşfettiğim bir şey: işlevi çağırmadan önce boş kontrol:

a = b && b.length;

Bu daha kısa bir eşdeğerdir:

a = b ? b.length : null;

En iyi bölüm, bir mülk zincirini kontrol edebilmenizdir:

a = b && b.c && b.c.length;

1

Listelerle çalışmanın ne kadar basit olduğunu seviyorum:

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

Ve karmalar:

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

Diğer dillerin çoğunda bu oldukça ağır bir koddur. Varsayılan değer değerleri de güzel. Örneğin hata kodu raporlama:

var errorDesc = {301: "Moved Permanently",
                 404: "Resource not found",
                 503: "Server down"
                }[errorNo] || "An unknown error has occurred";

Harika görünüyor, bunun teknik adı nedir?
TrySpace

0

int'den dizeye döküm

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

3
Bu bana düz bir i.toString () veya String (i) yapmaktan daha "şekerli" görünmüyor. Kısa! = Şeker.
Ateş Göral

0
element.innerHTML = "";  // Replaces body of HTML element with an empty string.

Öğenin tüm alt düğümlerini silmek için bir kısayol.


6
Bu gerçekten Javascript değil, DOM ve şu anda bu konuda standart değil.
05'te gözkapağı kaybı

0

Dize, tam sayıya, imkansızsa varsayılan olarak 0'a dönüştür

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

Bazı durumlarda yararlı olabilir, çoğunlukla 0 kötü sonuç olarak kabul edildiğinde


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.