JavaScript'teki işlevleri tanımlamak için const'un doğru kullanımı


183

constJavaScript'te ne tür değerlerin ayarlanabileceğine ilişkin sınırlamalar olup olmadığını, özellikle de işlevleri ilgilendiriyorum . Bu geçerli mi? İşe yarıyor, ancak herhangi bir nedenle kötü uygulama olarak kabul ediliyor mu?

const doSomething = () => {
   ...
}

ES6'da tüm fonksiyonlar bu şekilde tanımlanmalı mıdır? Öyle görünüyorsa, bu yakalanmış gibi görünmüyor.

Herhangi bir yorum için teşekkürler!


Birden çok soru soruyor gibi görünüyorsunuz: 1) "JavaScript'te" No 2) const kullanılarak ne tür değerlerin ayarlanabileceğine dair herhangi bir sınırlama olup olmadığını merak ediyorum "Bu geçerli mi?" Evet. 3) "herhangi bir nedenden ötürü kötü bir uygulama olarak görülüyor mu?" Sanırım bu konuda bir şey söyleyecek kadar uzun sürmedi ama bunun neden ped uygulaması olması gerektiğini anlamıyorum. Bundan çok farklı değil var doSomething = <function def>;. 4) "ES6'da tüm fonksiyonlar bu şekilde tanımlanmalı mı?" Bana hantal geliyor. İşlev bildirimlerini seviyorum. Herkes kendi.
Felix Kling

1
Gördüğüm gibi (görüş, bir gerçek değil), yeniden tanımlayan işlevlere izin vermemek mantıklı. İster aklı başında olsun, ister işlevsel bir kullanımı olup olmadığı tartışmalıdır. Kullanım senaryosuna uyduğunu düşünüyorsanız, birinin kararınızı tartışabileceğini ve kötü uygulama olarak değerlendirebileceğini sanmıyorum.
Mjh

4
Sanırım soru neyi başarmak istediğinizdir const. İşlevi geçersiz kılmayı önlemek istiyor musunuz? Zaten bunu yapmamak için kodunuzu bildiğinizi varsayarım. Niyetini doSomething, yani bir işlevi tuttuğunu ve değerini değiştirmediğini ifade etmek ister misiniz ? Bence işlev bildirimleri de bu amacı açıkça ifade ediyor. Bu nedenle, geçersiz kılmadan "çalışma zamanı korumasına" ihtiyacınız varsa, bunun için gidin. Aksi takdirde fazla fayda görmüyorum. Tabii ki eğer eskiden kullanırsanız var foo = function() {};, constonun yerine kullanırdım var.
Felix Kling

5
@FelixKling, "Yine de bunu yapmamanız için kodunuzu bildiğinizi varsayarım." - bu oldukça kötü bir argüman. Aksi takdirde, hiçbir anlamı yoktur const.
meandre

Yanıtlar:


254

Yaptıklarınızla ilgili bir sorun yok, ancak işlev bildirimleri ile işlev ifadeleri arasındaki farkı hatırlamanız gerekir.

Bir işlev bildirimi, yani:

function doSomething () {}

Tamamen kapsamın üst kısmına çekilir (ve benzeri letve constonlar da blok kapsamlıdır).

Bu, aşağıdakilerin işe yarayacağı anlamına gelir:

doSomething() // works!
function doSomething() {}

Bir işlev ifadesi, yani:

[const | let | var] = function () {} (or () =>

Anonim bir işlevin ( function () {}) oluşturulması ve bir değişkenin oluşturulması ve ardından o anonim işlevin bu değişkene atanmasıdır.

Dolayısıyla, bir kapsam içindeki değişken kaldırma ile ilgili genel kurallar - blok kapsamındaki değişkenler ( letve const) undefinedblok kapsamlarının en üstünde olduğu gibi kaldırılmaz .

Bu şu anlama gelir:

if (true) {
    doSomething() // will fail
    const doSomething = function () {}
}

doSomethingTanımlanmadığı için başarısız olur . (A atar ReferenceError)

Kullanıma geçerseniz var, değişkenin kaldırılmasını sağlarsınız, ancak undefinedyukarıdaki kod bloğunun hala çalışmayacağı şekilde başlatılır . (Bu atacağınız TypeErrorandan itibaren doSomethingonu çağırdığınız zaman bir işlev değildir)

Standart uygulamalara gelince, her zaman iş için uygun aracı kullanmalısınız.

Axel Rauschmayer, es6 anlambilimi de dahil olmak üzere kapsam ve kaldırma konusunda harika bir yazıya sahiptir: ES6'da Değişkenler ve Kapsam Belirleme


7
Sadece es6 sınıflarının sınıf adını sınıf içinde yeniden atanmasını önlemek için dahili olarak const kullandığını eklemek isterim.
user2342460

2
Arasındaki bir ince bir fark , bir function a(){console.log(this);} ve b const a=_=>{console.log(this);} sizin gibi dersek olduğunu a.call(someVar);yılında, bir , bu yazdırılır someVariçinde, b , bu yazdırılır window.
Qian Chen

100

constİşlevleri tanımlamak için kullanmak bir kesmek gibi görünse de, onu üstün kılan bazı büyük avantajlarla birlikte geliyor (bence)

  1. İşlevi değiştirilemez hale getirir, bu nedenle bu işlevin başka bir kod parçası tarafından değiştirilmesi konusunda endişelenmenize gerek yoktur.

  2. Daha kısa ve daha temiz olan yağ ok sözdizimini kullanabilirsiniz.

  3. Ok işlevlerini kullanmak thissizin için bağlayıcılığı sağlar.

ile örnek function

// define a function
function add(x, y) { return x + y; }

// use it
console.log(add(1, 2)); // 3

// oops, someone mutated your function
add = function (x, y) { return x - y; };

// now this is not what you expected
console.log(add(1, 2)); // -1

ile aynı örnek const

// define a function (wow! that is 8 chars shorter)
const add = (x, y) => x + y;

// use it
console.log(add(1, 2)); // 3

// someone tries to mutate the function
add = (x, y) => x - y; // Uncaught TypeError: Assignment to constant variable.
// the intruder fails and your function remains unchanged


1
Ve iki kez işlev ekleme (x, y) bildirebilirsiniz, ancak iki kez const add = ...
bildiremezsiniz

33
1. Değişmezlik gerçek bir faydadır, ancak birisinin bir fonksiyonun üzerine yazması çok nadirdir. 2. İşleviniz bir ifade olamazsa, yağ oku sözdizimi daha kısa değildir. function f(x, y) {18 karakter, const f = (x, y) => {21 karakter, yani 3 karakter daha uzun. 3. Bu bağlamayı korumak, işlevler bir yöntem (veya bunu anlamlı kılan başka bir işlev) içinde tanımlanmışsa önemlidir. Üst düzey komut dosyasında anlamsızdır. Yanlış yaptığınızı söylemiyorum, sadece belirttiğiniz nedenler çok alakalı değil.
Nakedible

@Nakedible başka geçerli nedenler nelerdir?
Anish Ramaswamy

13
Eski moda işlev sözdiziminin bir avantajı, hata ayıklama sırasında bir adı olmasıdır.
user949300

3
Fonksiyon bildiriminin yeniden bağlanmasını önlemek için linterleri kullanırdım.
Franklin Yu

32

Bu sorunun sorulmasından bu yana üç yıl geçti, ama şimdi karşımıza çıkıyorum. Bu cevap şu ana kadar yığının altında olduğundan, lütfen tekrarlamama izin verin:

S: JavaScript'te const kullanılarak ne tür değerlerin ayarlanabileceği konusunda herhangi bir sınırlama olup olmadığı konusunda ilgileniyorum - özellikle işlevler. Bu geçerli mi? İşe yarıyor, ancak herhangi bir nedenle kötü uygulama olarak kabul ediliyor mu?

Birini gözlemledikten sonra biraz araştırma yapmak motive edilmiş üretken JavaScript kodlayıcısı kim daima kullanır constiçin açıklama functionsgörünürde bir neden / fayda olmasa bile,.

Cevap olarak " herhangi bir nedenle kötü bir uygulama olarak kabul nedir? " IMO, evet öyle, ya da en azından, orada, bana diyelim avantajları kullanarak functiondeyimi.

Bana öyle geliyor ki bu büyük ölçüde bir tercih ve stil meselesi. Yukarıda sunulan bazı iyi argümanlar var, ancak hiçbiri bu makalede açıklandığı gibi net değil:

Sürekli karışıklık: neden hala medium.freecodecamp.org/Bill Sourour, JavaScript guru, danışman ve öğretmen tarafından JavaScript işlev ifadelerini kullanıyorum .

Zaten bir karar vermiş olsanız bile herkesi bu makaleyi okumaya çağırıyorum.

İşte ana noktalar:

İşlev deyimlerinin [const] işlev ifadelerine göre iki belirgin avantajı vardır:

Avantaj # 1: Niyetin netliği

Günde binlerce kod satırı tararken, programcının amacını olabildiğince hızlı ve kolay bir şekilde bulmak yararlıdır.

Avantaj # 2: Beyanname sırası == icra sırası

İdeal olarak, kodumun çalıştırılmasını beklediğim sırada daha fazla veya daha az beyan etmek istiyorum.

Bu benim için gösterici: const anahtar sözcüğü kullanılarak bildirilen herhangi bir değere, yürütme ulaşana kadar erişilemez.

Yukarıda açıkladığım şey bizi baş aşağı görünen bir kod yazmaya zorlar. En düşük seviye işlevle başlamalı ve yukarı çıkmalıyız.

Beynim bu şekilde çalışmıyor. Bağlamı ayrıntılardan önce istiyorum.

Çoğu kod insanlar tarafından yazılmıştır. Bu nedenle, çoğu insanın anlama düzeninin, çoğu kodun yürütme sırasını kabaca izlemesi mantıklıdır.


1
Niyetin netliği hakkında biraz daha yorum yapabilir misiniz? # 2 alıyorum, ancak # 1'in anlayabildiği kadarıyla # 2'nin (ön?) Yinelemesi. Ben bir durumda, yani sonra kendi defaultErrorHandlersöz işleyicileri çağırabilirsiniz anonim bir işlev olarak atanmış kendi const sahip işlevleri düşünebilirsiniz . Bu, gerektiğinde işlevler içindeki bu varsayılan hata işleyiciyi isteğe bağlı olarak 'geçersiz kılmamı' sağlar. Bazılarının sadece bir hata nesnesi döndürmesi gerekir, diğerleri ise farklı seviyelerde ayrıntılar içeren bir http yanıtı döndürmelidir. Yine de kod yapısı ne olursa olsun tanıdık bir model olabilir.
Jake T.

Belki de fikrim çok kıvrımlı! Sadece kafamı bazı yeni uygulamaların etrafına sarmak, henüz bunları uygulamak için çok zaman harcamamıştım. Sadece aramayı .then( res.success, res.error )ilan ettiğim anonim işlevlerden çok daha fazla hoşlandığımı bulmak res.success(value);. Ortak bir .then( ..., defaultErrorHandler)desene sahip olmak, üst düzey tanımlı defaultErrorHandler işleviyle güzel olabilir ve isteğe bağlı const defaultErrorHandler = error => { ... }olarak istenen şekilde bir işlev kapsamı içinde bildirilebilir.
Jake T.

1
@JakeT. RE "Niyetin netliği hakkında biraz daha yorum yapabilir misiniz?". Her şeyden önce, bu ifade benim değil, o makalenin yazarı freecodecamp.org/Bill Sourour tarafından yapıldı. Ama bu benim için gerçekten sağduyu. Eğer "yarın () fonksiyonu" okursam hemen bir fonksiyon olduğunu biliyorum. Ama eğer "const tomorrow = () =>" okursam, bir an dururum ve nihayet belirlemek için kafamdaki sözdizimini ayrıştırırım, tamam, evet, bu bir işlev.
JMichaelTX

1
Başka bir şey, başka biri tarafından yazılmış uzun bir komut dosyası varsa ve tüm fonksiyonları görmek istiyorum, onları bulmak için "fonksiyon" hızlı bir arama yapabilirsiniz. Ya da daha iyisi, tüm fonksiyonları çıkarmak için hızlı bir JS RegEx yazabilirim. IMO, "const" deyimi sadece değişmeyecek veriler (işlevler için değil) içindir.
JMichaelTX

10

Kullanımının çok önemli bazı faydaları vardır constve bazıları, ne kadar kasıtlı ve gösterge edici olduğu için mümkün olan her yerde kullanılması gerektiğini söyleyebilir.

Anlayabildiğim kadarıyla, JavaScript'teki değişkenlerin en gösterge niteliğindeki ve öngörülebilir beyanı ve ne kadar kısıtlı olduğuna dair en kullanışlılarından biri. Neden? Çünkü mevcut olan bazı olasılıkları varve letbeyanları ortadan kaldırır .

Bir okurken ne çıkarabilirsin const? Aşağıdakilerin tümünü, yalnızca constbildirim deyimini okuyarak VE bu değişkene yapılan diğer referansları taramadan bilirsiniz :

  • değer bu değişkene bağlıdır (temel nesnesi derinden değişmez olmasına rağmen)
  • hemen içerdiği bloğun dışında erişilemez
  • Geçici Ölü Bölge (TDZ) kuralları nedeniyle bağlamadan önce hiçbir zaman bağlayıcıya erişilmez.

Aşağıdaki alıntı ve öğelerinin yararlarını tartışan bir makaleden alınmıştır . Ayrıca, anahtar kelimenin kısıtlamaları / sınırları hakkındaki sorunuzu daha doğrudan yanıtlar:letconst

Tarafından sunulanlar gibi kısıtlamalar letve constkodun anlaşılmasını kolaylaştırmanın güçlü bir yoludur. Yazdığınız kodda bu kısıtlamalardan mümkün olduğunca fazlasını elde etmeye çalışın. Bir kod parçasının ne anlama gelebileceğini sınırlayan daha açıklayıcı kısıtlamalar, insanların gelecekte bir kod parçasını okuması, ayrıştırması ve anlaması daha kolay ve hızlıdır.

Verilen bir constdeklarasyona deklarasyondan daha fazla kural var var: blok-kapsam, TDZ, beyanda tayin, yeniden atama yok. Oysa varifadeler sadece işlev kapsamını gösterir. Bununla birlikte, kural sayma çok fazla fikir vermiyor. Bu kuralları karmaşıklık açısından tartmak daha iyidir: kural karmaşıklık ekler veya çıkarır mı? constBlok kapsam belirleme durumunda, fonksiyon kapsam belirlemeden daha dar bir kapsam anlamına gelir, TDZ, beyandan önce kullanımı tespit etmek için kapsamı beyandan geriye doğru taramamız gerekmediği anlamına gelir ve atama kuralları, bağlamanın her zaman aynı referans.

Daha kısıtlı ifadeler, bir kod parçası daha basit hale gelir. Bir ifadenin ne anlama gelebileceğine kısıtlamalar ekledikçe, kod daha az tahmin edilemez hale gelir. Bu, statik olarak yazılmış programların okunmasının genellikle dinamik olarak yazılmış programlardan daha kolay olmasının en büyük nedenlerinden biridir. Statik yazım, program yazarına büyük bir kısıtlama getirir, ancak aynı zamanda programın nasıl yorumlanabileceği konusunda büyük bir kısıtlama getirerek kodunun anlaşılmasını kolaylaştırır.

Bu argümanları göz önünde bulundurarak, constbize düşünebileceğimiz en az imkânı veren ifade olduğu için mümkün olan yerlerde kullanmanız önerilir .

Kaynak: https://ponyfoo.com/articles/var-let-const

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.