ES6 / Typescript'te ok işlevleriyle _ (alt çizgi) değişkenini kullanma


121

Bu yapıya Açısal bir örnekte rastladım ve bunun neden seçildiğini merak ediyorum:

_ => console.log('Not using any parameters');

_ Değişkeninin umursamıyor / kullanılmıyor anlamına geldiğini anlıyorum, ancak tek değişken olduğu için _ kullanımını tercih etmek için herhangi bir neden var mı:

() => console.log('Not using any parameters');

Elbette bu, yazmak için bir karakter eksik olamaz. () Sözdizimi, bence amacı daha iyi iletiyor ve aynı zamanda daha fazla türe özgü çünkü aksi halde ilk örneğin şöyle görünmesi gerektiğini düşünüyorum:

(_: any) => console.log('Not using any parameters');

Önemli olması durumunda, kullanıldığı bağlam şuydu:

submit(query: string): void {
    this.router.navigate(['search'], { queryParams: { query: query } })
      .then(_ => this.search());
}


1
Asla kullanılmayan bir parametre için yazma veya tip özgüllüğü konusunda nasıl endişelenebilirsiniz?

3
Ben bir C ++ geliştiricisiyim, bu yüzden sanırım her zaman tür özgüllüğü konusunda endişeliyim :-).
Dur

7
Kişisel olarak, _ => kalıbı köşeli parantez sayısını azaltarak okumayı kolaylaştırır: doStuff (). Sonra (() => action ()) vs doStuff (). Sonra (_ => action ()).
Damien Golding

Yanıtlar:


95

Bu stilin kullanılabilmesinin (ve muhtemelen neden burada kullanılmasının) nedeni _, bundan bir karakter daha kısa olmasıdır ().

İsteğe bağlı parantezler, isteğe bağlı küme parantezleriyle aynı stil sorununa girer . Bu, çoğunlukla bir zevk ve kod stili meselesidir, ancak burada tutarlılık nedeniyle ayrıntılar tercih edilmektedir.

Ok fonksiyonları parantezsiz tek bir parametreye izin verirken, sıfır, tek yok edilmiş, tek dinlenme ve birden çok parametre ile tutarsızdır:

let zeroParamFn = () => { ... };
let oneParamFn = param1 => { ... };
let oneParamDestructuredArrFn = ([param1]) => { ... };
let oneParamDestructuredObjFn = ({ param1 }) => { ... };
let twoParamsFn = (param1, param2) => { ... };
let restParamsFn = (...params) => { ... };

Altı çizili parametreler için TypeScript 2.0'dais declared but never used hata düzeltilmiş olsa _da unused variable/parameter, bir linter veya IDE'den uyarı da tetikleyebilir . Bu, bunu yapmaya karşı önemli bir argümandır.

_görmezden gelinen parametreler için geleneksel olarak kullanılabilir (diğer cevabın zaten açıklandığı gibi). Bu kabul edilebilir kabul edilebilirken, bu alışkanlık _Alt Çizgi / Lodash ad alanıyla bir çelişkiye neden olabilir , ayrıca birden fazla göz ardı edilen parametre olduğunda kafa karıştırıcı görünür. Bu nedenle, uygun şekilde adlandırılmış altı çizili parametrelere sahip olmak yararlıdır (TS 2.0'da desteklenir), ayrıca işlev imzasını ve parametrelerin neden göz ardı edildiğini anlamada zaman kazandırır (bu, _kısayol olarak parametrenin amacına aykırıdır ):

let fn = (param1, _unusedParam2, param3) => { ... };

Yukarıda sıralanan nedenlerden dolayı, ben şahsen _ => { ... }kod stilini kaçınılması gereken kötü bir ton olarak düşünürdüm .


1
Bir karakter daha kısadır, ancak çoğu IDE için aynı tuşa basma miktarıdır, çünkü tuşuna basmak (genellikle bir ). Şahsen pparametre için kullanmayı tercih ediyorum, ayrıca herhangi bir performans sorunu olup olmadığını da merak ediyorum
Mojimi

69

()Sözdizimi niyet daha iyi IMHO yaymaktadır ve aynı zamanda daha fazla tip özeldir

Tam olarak değil. ()işlevin herhangi bir argüman beklemediğini, herhangi bir parametre bildirmediğini söylüyor. Fonksiyon .length0'dır.

Eğer kullanırsanız _, fonksiyonun bir argüman iletileceğini, ancak sizin onu umursamadığınızı açıkça belirtir. İşlev .length, bazı çerçevelerde önemli olabilecek 1 olacaktır.

Dolayısıyla, tür açısından bakıldığında, yapılması daha doğru bir şey olabilir (özellikle yazmadığınız zaman anyama diyelim ki _: Event). Ve dediğin gibi, yazmak için bir karakter daha az, bu da bazı klavyelerde ulaşılması daha kolay.


6
İlk düşüncem, işlevi anlamaya çalışırken göz önünde bulundurulması gereken hiçbir argüman olmadığını sadece geleneksel olarak açık hale getirdiğiydi. () Kullanmak bunu açık hale getirir, olası bir _ kullanımı için kodun taranmasına gerek yoktur (bu kural ihlal eder). Ancak, işleve geçirilen bir değer olduğunu belgelemenin değerini de düşünmek için gözlerimi açtınız, aksi takdirde her zaman açık olmayacaktı.
Dur

_()
Kodumun

25

Sanırım _ =>sadece kullanılıyor () =>çünkü _JS'deki gibi parametrelerin çıkarılmasına izin verilmeyen diğer dillerde yaygındır.

_ Go'da popülerdir ve Dart'ta da bir parametrenin ve muhtemelen bilmediğim diğerlerinin göz ardı edildiğini belirtmek için kullanılır.


4
Python da bu kuralı takip ediyor sanırım.
Jaime RGP

7
Bu kullanımı _, muhtemelen ML ve Haskell gibi işlevsel dillerden ödünç alınmıştı; burada, Python'un icadından (Go, Dart veya TypeScript bir yana) uzun zamandır önce geldi.
ruakh

1
Ruby bunu da yapıyor ( po-ru.com/diary/rubys-magic-underscore ) ve F # da (ve ML ailesinden etkilenen diğer diller)
Mariusz Pawelski

Scala alt çizgiyi sever ( includehelp.com/scala/use-of-underscore-in-scala.aspx ). Scala'nın alt çizgili anonim türlerle yaptıklarından sonra hangi diller kullanıldı.
Sam

Sanırım Scala da başka bir dilden aldı. 70'lerde zaten var olmayan programlama dillerinde neredeyse hiçbir şey yoktur: D Çoğunlukla malzemeleri birleştirmenin yeni yolları.
Günter Zöchbauer

11

İki kullanım arasında ayrım yapmak mümkündür ve bazı çerçeveler bunu farklı geri arama türlerini temsil etmek için kullanır. Örneğin, düğümlerin ifade çerçevesinin bunu ara yazılım türleri arasında ayrım yapmak için kullandığını düşünüyorum, örneğin hata işleyicileri üç bağımsız değişken kullanırken, yönlendirme iki bağımsız değişken kullanıyor.

Böyle bir farklılaşma aşağıdaki örneğe benzeyebilir:

const f1 = () => { } // A function taking no arguments
const f2 = _ => { }  // A function with one argument that doesn't use it

function h(ff) { 
  if (ff.length === 0) {
    console.log("No argument function - calling directly");
    ff();
  } else if (ff.length === 1) {
    console.log("Single argument function - calling with 1");
    ff(1);
  }
}

h(f1);
h(f2);


1
Bu Bergi'nin cevabına dayanıyor, ancak bir örnek eklemenin başka birinin gönderisine yapmaktan mutlu olduğumdan biraz daha fazla düzenleme olduğunu düşündüm.
Michael Anderson

0

Yazıyı yazdığımda, izlenim altındayım, _ok fonksiyonlarını kullanmadan yaratmanın tek yoluydu (), bu da kullanmanın _bazı küçük avantajları olabileceğine inanmamı sağladı, ancak yanılmışım. @Halt, diğer değişkenler gibi davrandığını yorumlarda doğruladı, özel bir dil yapısı değil.


Kendimi test ederken bu altçizgi ok fonksiyonları hakkında hiçbir yerde bahsetmediğim bir şeyden daha bahsetmek istiyorum. Sen edebilirsiniz parametre olarak işlev alt çizgi kullanmak buna beri bu muhtemelen tasarlanmamıştır kullanım kullanılmayan bir parametreyi temsil gerekiyordu rağmen. Netlik için, bu şekilde kullanmayı gerçekten tavsiye etmem. ancak kod golfü , en kısa kodu yazdığınız zorluklar gibi şeyleri bilmek faydalı olabilir (her karakteri onsuz da kullanabilirsiniz ()). Kütüphanelerin bunu kullandığı bazı gerçek kullanım durumlarını hayal edebiliyorum ve bu işlevselliği istemeseler bile onu kullanmanız gerekir.

Misal:

// simple number doubling function
f = _=> {
    _ = _ * 2;
    return _;
}

console.log(f(2)); // returns 4
console.log(f(10)); // returns 20

Chrome konsolu, Sürüm 76.0.3809.132 (Resmi Yapı) (64 bit) ile test edilmiştir


1
Alt çizgi '_' yasal bir değişken adıdır ve özel bir dil yapısı değildir, yalnızca geleneksel olarak özel bir anlam verilmiştir. Kullanılmayan parametrelerle ilgili Linter uyarıları, alt çizgi öneki kullanılarak susturulabilir. Sanırım _ tek başına kullanılmamış demenin en kısa yolu.
Dur

@Halt Açıklama için teşekkürler, kesinlikle bilmek güzel. Aslında bu yazıyı yapmadan ()önce ok işlevlerini yapabileceğinizi bilmiyordum _, bunun tek yolunun bu olduğunu düşündüm , bu yüzden bunu belirtmeye karar verdim. Bunu akılda tutarak, normal bir karakter kullanabileceğiniz için golf oynamak için bile özel bir şey olmadığı ortaya çıkıyor. Söylediğiniz gibi, sadece kuralları takip etmek için daha iyi kullanılır.
Matsyir
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.