ES6'da 'let' vs 'const'ı ne kadar kullanmalıyım?


214

Son zamanlarda io.js için bir sürü ES6 kodu yazıyorum. Doğada öğrenilecek çok fazla kod yok, bu yüzden kendi sözleşmelerimi giderken tanımladığımı hissediyorum.

Benim sorum ne zaman constvs kullanılacağı ile ilgili let.

Bu kuralı uyguluyorum: Mümkünse, kullanın const. Sadece letdeğerinin değişmesi gerektiğini biliyorsanız kullanın . (Her zaman geri dönebilir ve a'yı bir a constile değiştirebilir ve letdaha sonra değerini değiştirmeniz gerekir.

Bu kuralın ana nedeni, tutarlı bir şekilde uygulanması kolaydır. Gri alan yok.

Mesele şu ki, bu kuralı uyguladığımda pratikte beyanlarımın% 95'i const. Bu bana çok garip geldi. Sadece kullanıyorum letgibi şeyler için ibir de for(gerçek hayatta çok gelip etmeyen) birikmiş Fibonacci toplamları gibi şeyler için zaman zaman döngü veya. Buna şaşırdım - ES5 kodumdaki "değişkenlerin"% 95'inin değişmeyen değerler için olduğu ortaya çıktı. Ama kodumun consther yerini görmek bir şekilde yanlış geliyor.

Öyleyse sorum şu: constbu kadarını kullanmak tamam mı? Gerçekten böyle şeyler yapmalı mıyım const foo = function () {...};?

Ya da constbir modülün tepesinde bir değişmezi kodladığınız durumlarda - örneğin büyük harflerle yaptığınız gibi - böyle const MARGIN_WIDTH = 410;mi?


7
Bu sorunun öncelikle görüşe dayalı olduğunu ve bu nedenle kapatılma ihtimalinin bulunduğundan şüpheliyim, ancak 2 sentim: Bunu kullanmak sorun constdeğil.
jhominal

15
function foo() {...}daha iyidir<anything> foo = function() {...}
OrangeDog

12
@OrangeDog Bunun için açıklamanızı görmek isterim, çünkü tam tersi bir sonuç çıkardım. function foo() {...}Kaldırma nedeniyle, kaldırma nedeniyle küçük kafa karışıklığına neden olabilecek bir uyarı vardır . Ayrıca, onun varlığı aynı şeyi yapan iki yapımız olduğu anlamına gelir; ancak bunlardan biri yalnızca çok özel bir bağlamda çalışır. (Bir ifadenin var olabileceği herhangi bir yerde bir işlev ifadesi kullanabilirsiniz, ancak yalnızca ifade düzeyinde bir işlev bildirimi kullanabilirsiniz.) Kısalık tercih ederseniz, sorun yalnızca işlev ifadesi sözdiziminin tüm kelimeyi kullanması olabilir function.
Keen

11
Yığın izleri, anon yerine işlevin adını taşır. Kaldırma iyidir ve foo undefined konusunda endişelenmenize gerek kalmadan fonksiyonları doğal bir düzende tanımlayalım.
OrangeDog

1
Bunlar akılda tutulması gereken iyi noktalar, ancak henüz ikna olmadım. Modern hata ayıklayıcılar, hangi sembole atadığınızı temel alarak (varsa - adlandırılmış bir fonksiyon ifadesi kullanabilirsiniz) fonksiyonunuz için doğru ekran adını seçmek için iyi bir iş çıkarır. Doğal işlev bildirimi sırası oldukça özneldir. Doğal düzenin temel parçaları tanımlamakla başlamak olduğunu düşünmek ve sonra bunları kullanan parçaları tanımlamak makul olabilir.
Keen

Yanıtlar:


183

Buradaki cevabım javascript'e özgü değil.

Bunu yarı kolay bir şekilde yapmamı sağlayan herhangi bir dilde bir kural olarak, her zaman mümkünse dilinizde ne denirse const / final / readonly / 'i kullanın. Sebep basittir, neyin değişebileceği ve neyin değişmeyeceği belli olmadığı zaman kodla ilgili sebepler çok daha kolaydır. Buna ek olarak, birçok dilde, yanlışlıkla const olarak ilan ettiğiniz bir değişkene atadığınızda, yanlış bir şey yaptığınızı söyleyen araç desteği alabilirsiniz.

Geri dönüp bir kursa izin vermek çok kolaydır. Ve varsayılan olarak const gitmeden önce iki kez düşünmenizi sağlar. Ve bu çoğu durumda iyi bir şeydir.

Beklenmedik şekilde değişen değişkenleri içeren kaç hata gördünüz? Çok fazla tahmin ediyorum. Gördüğüm hataların çoğunun beklenmeyen durum değişimlerini içerdiğini biliyorum. Tüm bu hataları liberal bir şekilde const kullanarak kurtulmayacaksın, ama birçoğundan kurtulacaksın!

Ayrıca, birçok işlevsel dil, tüm değişkenlerin varsayılan olarak const olduğu değişken değişkenlere sahiptir. Erlang'a bakınız, örneğin ya da F #. Atama olmadan kodlama bu dillerde mükemmel çalışır ve insanların işlevsel programlamayı sevmelerinin birçok nedeninden biridir. Daha iyi bir programcı olmak için bu dillerden devleti yönetme hakkında çok şey var.

Ve her şey const ile son derece liberal olmakla başlar! ;) Yazmak için iki karakter daha yazalım, o yüzden devam et ve consther şey!


45
constiki karakterden daha fazla let...
OrangeDog

72
Ancak değişmezden 5 karakter daha az.
Cerad

7
Bu val, Scala'da (değişmez olarak değişken olduğunu bildiren) kullanma ve varkullanamadığımız zaman kullanmanın (değişken eşdeğeri) kullanımına çok benziyor val. Başka bir deyişle, değişkenleri varsayılan olarak değişmez olarak ilan ediyoruz ve yalnızca tam olarak ihtiyaç duyduğumuzda mutasyona neden oluyoruz (bu, yalnızca değişken yaklaşımın daha temiz olması nedeniyle olabilir).
Kat

7
Bu cevabı kabul ediyorum, ancak düz nesneler veya diziler gibi şeylerle çalışırken nesnelerin 'const' ile tanımlanmış olsalar bile, özellikleri değişebileceği kadar açık olmadığını unutmayın. Object.freeze gibi çalışmayı 'const' yapmayı düşünmüştüm ama durum böyle değil.
23'te backdesk

2
@Cerad “4 karakter daha az” mı demek istedin yoksa burada şaka mı kaçırıyorum?
Mathias Bynens

57

Dikkat edin, çünkü constnesne tuşları değişkendir.

Buradan: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const

nesne anahtarları korunmuyor

bu örneği düşünün:

const colors = {red: "#f00"}; 
console.log(colors); // { "red": "#f00" }

colors.red = "#00f";
colors.green = "#0f0";
console.log(colors); // { "red": "#00f", "green": "#0f0" }

Diziler için aynı şey:

const numbers = [1, 2, 3];
console.log(numbers); // [ 1, 2, 3 ]

numbers.push(4);
console.log(numbers); // [ 1, 2, 3, 4 ]

Tamamen kendime karar vermedim, ancak consttüm dizi / nesne olmayan nesneler letiçin kullanmayı ve nesneler / diziler için kullanmayı düşünüyorum .


34
Doğru, ancak beklenen IMO - sabit olan şey, size atanan nesne başvurusudur const. colors = numbersbeklendiği gibi çalışmayacak. Eğer nesne özelliklerini korumak istiyorsanız kullanabilirsiniz Object.freeze() developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
Josef Engelfrost

16
Yanıltıcı. Değişmez. Ancak asıl nesne özellikleri değildir.
Gaston Sanchez

1
+1 Evet, referans korunur, ancak soru açısından,const moment = require('moment') birinin moment = dead.fish(() => pizza)daha sonra yapmaya çalışacağından endişe duyan bir kişi olmadığınız sürece, bu gibi durumlarda kullanmak çok saçmadır .
Saat

5
Belki de endişelenmek için daha gerçekçi moment = Date.now(). Ancak, her durumda, kod değişmez bir varsayım varsa, mümkün olduğunda onu zorlamakta yanlış bir şey göremiyorum.
James M.

3
Kimse değişmez olmadıklarını söylemedi. Genel olarak yanlış anlaşılması, const'ın amacının değiştirilemez hale getirilmesi olduğunu, gerçekten de adın başlatıldığından farklı bir nesneye atıfta bulunmayacağının garantisidir.
monokrome

25

Endişelenme. constJavaScript’e harika bir eklenti ve mantıklı olan her yerde kullanmanızı tavsiye ederim. Daha sağlam kod için yapar.

Nesneler söz konusu olduğunda constdeğişkeninizi yeniden atamadan koruyacaktır, ancak değişmez nesnelere ihtiyacınız varsa, Object.freezeyönteme ihtiyacınız olacaktır , aşağıya bakın.

const immutableOject = Object.freeze({immutableProperty: 'foo'});

constyalnızca yeniden atamadan koruyacak ve freezeyöntem tüm anında özellikleri koruyacaktır. Bütün iç içe geçmiş özelliklerin de değişmez olması gerekiyorsa, freezebunları tekrar tekrar yapmanız gerekir .


14
Object.freezeSığ olduğuna dikkat edin .
Mathias Bynens

@MathiasBynens Bu yoruma rastladım ve tam olarak ne demek istediğinizi merak ediyorum. Lütfen detaylandırır mısın?
Cole Roberts

@ColeRoberts Sığ değişmezlik kavramı, nesne referansının kendisinin değişmez olduğu, ancak özelliklerin hala değiştirilebildiği zamandır. Const anahtar sözcüğü yalnızca sığ değişmezliği sağlar, bu nedenle tüm özelliklerin değişmez olması gerekiyorsa Object.freeze kullanmanız gerekir.
clean_coding

3
@ColeRoberts Dondurulmuş bir nesne (yani iç içe geçmiş nesneler) içindeki nesne değerlerinin hala değiştirilebileceği anlamına gelir. Daha fazla bilgi için mathiasbynens.be/notes/es6-const#immutable-values ​​adresini ziyaret edin.
Mathias Bynens

19

Benim içinde ES6 constdeğişmezlik ilgili değil yazı, ne açıklamak constspec göre tam demektir.

Bu nesnel gerçeklere dayanarak, benim kişisel tercihim:

[…] ES6 kodunuzda kullanımı letve constaşağıdakileri mantıklı kılar :

  • kullanmak constvarsayılan olarak
  • yalnızca letyeniden bağlama (yani herhangi bir yeniden atama şekli) gerektiğinde kullanın
  • ( varES6'da kullanılmamalıdır)

Olması gerektiği gibi öznel, bunun spec'in amacına en yakın olduğu bir gerçektir.

letVarsayılan olarak kullanan insanlar genellikle constdeğişkenleri sabit olarak görürler (ki bu zorunlu değil, tasarım gereğidir!). Her biri kendilerine göre, ancak amaçları amaçlarına göre kullanmayı tercih ediyorum, insanlar yanlış anlaşmaya dayanarak oluşturdukları bazı anlamlar için değil.

Kullanılması constsabitleri için sadece kullanmak gibidir HTML <aside>elemanı sadece yan çubuğu içeriği için.


2
constEğer sürekli değilse bir şeyi neden adlandırıyorsun ?
nu everest

3
@ nueverest Çünkü bunun için değil const. Yukarıdakileri okudun mu?
Mathias Bynens

2
@MathiasBynens Bence (sadece?) İle ilgili sorun constdenir const. İlk başta pek çok (tümü) geliştiriciyi şaşırtan aptal bir isimdir (javascript'te). IMO daha iyi constaranmış olsaydı let(özellikle letdaha kısa, ancak constçok daha yaygın olduğu için) ve letbaşka bir şey olarak adlandırılmış olsaydı daha iyi olurdu .
MrN00b,

@MathiasBynens Anladım ama neden öyle diyorsun? Bu sayfada görüldüğü gibi büyük bir karışıklık yaratıyor.
jtr13

4

Benim kişisel yaklaşımım, kodların okunabilirliği ve anlaşılmasına yardımcı olduğu düşüncesi:


letyalnızca kısa ömürlü değişkenler içindir, tek bir satırda tanımlanır ve sonra değiştirilmez. Genellikle sadece yazma miktarını azaltmak için var olan değişkenler. Örneğin:

for (let key in something) {
  /* we could use `something[key]` for this entire block,
     but it would be too much letters and not good for the
     fingers or the eyes, so we use a radically temporary variable
  */
  let value = something[key]
  ...
}

consttüm modül boyunca sabit olduğu bilinen tüm isimler için. Yerel olarak sabit değerler dahil değil. valueYukarıdaki örnekte, örneğin, kapsamı içinde sabittir ve ile ilan edilerek const, ancak birçok iterasyon vardır ve her biri için orada aynı olan bir değer olduğundan ismi , "değer" düşünce içine, o okuyucu yanıltabilirsiniz valueher zaman aynısı. Modüller ve fonksiyonlar constdeğişkenlerin en iyi örneğidir :

const PouchDB = require('pouchdb')
const instantiateDB = function () {}
const codes = {
  23: 'atc',
  43: 'qwx',
  77: 'oxi'
}

vardeğişken olan veya olmayan her şey için. Yerel olarak sabit olsalar bile let(ve basit bir doğrudan beyanda tamamlanmadıysa) uygun olmayan (yani basit bir doğrudan beyanda tamamlanmadı) bile, insanları kodları okuyanlarla karıştırabilecek isimler beyan edilmek için uygulanır var. Örneğin:

var output = '\n'
lines.forEach(line => {
  output += '  '
  output += line.trim()
  output += '\n'
})
output += '\n---'

for (let parent in parents) {
  var definitions = {}
  definitions.name = getName(parent)
  definitions.config = {}
  definitions.parent = parent
}

Daha yorum ve gelecekteki olası güncellemeleri burada .


10
Bu ikinci kod parçacığını silah gibi görünüyor.
Julian,

1

JavaScript, değişkenler fonksiyonlar ve bunun gibi olabileceği için biraz özeldir, ancak C #, Java veya başka bir C tarzı dilde düşünün:

const public void DoSomething()

Bu constgarip ve bu nedenle bu dillerdeki yöntem bildirimleri değişemez, başka bir şey haline getirildikten sonra, ne olursa olsun (var olabilecek bazı korkunç saldırıları gözardı ederek) yaptıkları budur.

JavaScript neden farklı olsun ki? Bu yüzden derlenmedi, ama bu derleyicilerin sağlayabileceği güvenliği ortadan kaldırmamız gerektiği anlamına gelmiyor. constAnahtar kelimeyi kullanmak bize daha fazla güvenlik sağlar, bu da kesinlikle daha sağlam uygulamalara yol açacaktır.

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.