JavaScript Const: ne zaman kullanılır ve gerekli mi?


349

Kısa süre önce constJavaScript'te anahtar kelimeyle karşılaştım. Söyleyebileceğim kadarıyla, değişmez değişkenler oluşturmak için kullanılır ve yeniden tanımlanamayacağından emin olmak için test ettim (Node.js'de):

const x = 'const';
const x = 'not-const';

// Will give an error: 'constant 'x' has already been defined'

Henüz tüm tarayıcılarda standartlaştırılmadığının farkındayım - ancak yalnızca Node.js V8 bağlamıyla ilgileniyorum ve bazı geliştiricilerin / projelerin , varanahtar kelime aynı etki.

Yani sorularım:

  • constYerinde ne zaman kullanılmalı var?
  • Yeniden atanmayacak bir değişken her bildirildiğinde kullanılmalı mıdır?
  • Bunun varyerine constveya tam tersi şekilde kullanılması gerçekten bir fark yaratır mı?

1
Bu henüz standartlaştırılmamış gibi görünüyor (belki EC6'da?). Bununla ilgili daha fazla bilgiyi burada bulabilirsiniz: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Sebastien C.

Yanıtlar:


462

Sorularınızın iki yönü vardır: constBunun yerine kullanmanın teknik yönleri varnelerdir ve bunu yapmanın insanla ilgili yönleri nelerdir.

Teknik fark önemlidir. Derlenmiş dillerde, bir sabit derleme zamanında değiştirilecek ve kullanımı, kodun çalışma zamanı verimliliğini daha da artırmak için ölü kod kaldırma gibi diğer optimizasyonlara izin verecektir. Son zamanlarda (gevşek kullanılan terim) JavaScript motorları daha iyi performans elde etmek için aslında JS kodunu derler, bu nedenle const anahtar sözcüğünü kullanmak, yukarıda açıklanan optimizasyonların mümkün olduğunu ve yapılması gerektiğini bildirir. Bu daha iyi performans sağlar.

İnsan ile ilgili yön, anahtar kelimenin anlambilimi ile ilgilidir. Değişken, değişmesi beklenen bilgileri içeren bir veri yapısıdır. Sabit, asla değişmeyecek bilgileri içeren bir veri yapısıdır. Hata için yer varsa, vardaima kullanılmalıdır. Bununla birlikte, bir programın ömründe asla değişmeyen tüm bilgilerin beyan edilmesi gerekmez const. Farklı koşullar altında bilgilerin değişmesi vargerekiyorsa, gerçek değişiklik kodunuzda görünmese bile bunu belirtmek için kullanın .


4
Şerefe, Mozilla / Google'ın JS motorlarına hiçbir sebepten ötürü const desteği eklemeyeceğini varsaydım. Mümkün olan yerlerde const kullandığınızdan emin olacağım.
axdg

6
constnesneleri değiştirilebilir gibi görünüyor, bu yüzden JS derleyicisinin gerçekten ne kadar katı olduğundan emin değilim. Belki "katı kullanın" modu da fark yaratır.
Rudie

9
@Rudie Aradığınız özelliğe nesnenin dondurulması denir . const"değişken" i başka bir değere yeniden atamayı önler. const a = {}; a = {};katı modda bir hata verir.
Tibos

Genelde çoğu değişken için izin yerine const kullanıyorum, tıpkı Java'da olduğu gibi çoğu değişken bildirime son ekledim.
kodlama

2
If there is room for error, var should always be used. Bugün bu geçerli değil, ESLint gibi araçlar consthemen ihlali gösteriyor .
vitaly-t

72

2017 Güncellemesi

Bu cevap hala büyük ilgi görüyor. Bu cevabın 2014'ün başında geri gönderildiğini ve o zamandan beri çok şey değiştiğini belirtmek gerekir.destek artık norm. Tüm modern tarayıcılar artık destekliyor, constbu yüzden sorunsuz bir şekilde kullanmak oldukça güvenli olmalı.


2014'ten Orijinal Yanıt

Oldukça iyi tarayıcı desteğine rağmen , şimdilik kullanmaktan kaçınırım. Gönderen MDN makalesindeconst :

Mevcut const uygulaması Mozilla'ya özgü bir uzantıdır ve ECMAScript 5'in bir parçası değildir. Firefox ve Chrome'da (V8) desteklenmektedir. Safari 5.1.7 ve Opera 12.00'dan itibaren, bu tarayıcılarda const içeren bir değişken tanımlarsanız, değerini daha sonra değiştirebilirsiniz. Internet Explorer 6-10'da desteklenmez, ancak Internet Explorer 11'de bulunur. Const anahtar sözcüğü şu anda işlev kapsamındaki sabiti bildirir (var ile bildirilen değişkenler gibi).

Sonra söylemeye devam ediyor:

constECMAScript 6 tarafından tanımlanacak, ancak farklı anlambilim ile tanımlanacak Let deyimi ile bildirilen değişkenlere benzer şekilde, const ile bildirilen sabitler blok kapsamına alınır.

Kullanmak yaparsanız constsize biraz eski tarayıcıları desteklemek için geçici bir çözüm eklemek zorunda gidiyoruz.


6
Büyük cevap - zaten MDN ile ilgili makaleyi okudum. Söylediğim gibi, V8'in gerçekten de kons. Sanırım @Tibos bunu temizledi.
axdg

James destek yönünü işaret ettiğiniz için teşekkürler. imho tüm javascript cevapları bir tarayıcı desteği dökümü içermelidir. güzel açıkladı
hubson bropa

4
Not ES6, Ağustos 2014'te bir özellik dondurma aldı. Temmuz 2015'te standart resmi olarak piyasaya sürüldü. Bunu şimdi okuyorsanız, kodunuz güncel bir motor tarafından yönetiliyorsa, kabul edilen yanıtı belirtilen şekilde izlemeniz gerektiği anlamına gelir.
Filip Dupanović

OP sorusu node.js'ye özgüdür
Nicu Surdu

@NicolaeSurdu emin. Ayrıca Ocak 2014'ten itibaren, muhtemelen 2017'de çoğunlukla gereksiz.
James Donnelly

41

Neden kullanıldığına göre const, @ Tibos'un cevabı harika.

Ama sen dedin:

Söyleyebileceğimden, değişmez değişkenler oluşturmak için kullanılır

Bu yanlış . Bir değişkeni değiştirmek, yeniden atamaktan farklıdır:

var hello = 'world' // assigning
hello = 'bonjour!' // reassigning

Const ile bunu yapamazsınız:

const hello = 'world'
hello = 'bonjour!' // error

Ancak değişkeninizi değiştirebilirsiniz:

const marks = [92, 83]
marks.push(95)
console.log(marks) // [92, 83, 95] -> the variable has been mutated.

Yani, değişkenin değerini değiştiren herhangi bir işlem yapmadan kullanarak =işareti değişken mutasyona edilir.

Not: +=örneğin ... yeniden atanıyor!

var a = 5
a += 2 // is the same as a = a + 2

Yani, sonuç olarak geçerli: constsizi engellemez mutasyona değişkenleri, bu engeller yeniden atama onları.


4
Ekstre "değişkenin değerini değiştiren herhangi bir işlem yapmadan kullanarak =işareti kısma olan" teknik yanlıştır. Örneğin, const marks=[92,83]; marks[2]=95; console.log(marks)çıktı alırsınız [92, 83, 95]. markseşittir işareti ile mutasyona uğramıştır.
chharvey

5
"Ama dedin ki: << Anlatabildiğim kadarıyla, değişmez değişkenler yaratmak için kullanılır >> Bu yanlıştır . Değişkeni değiştirmek yeniden atamaktan farklıdır" Hayır, öyle değil. Yeniden atama değişkeni değiştiriyor. Değişkende referansın başvurduğu nesneyi mutasyona uğratmaktan bahsediyorsunuz. Bu tamamen farklı bir şey.
TJ Crowder

Buraya var çünkü constdiziler bağlamında anlamaya çalışıyorum (kullanılan @chharvey örneğine benzer). Durumunda her seferinde yeniden atanmış olduğunu. Öyleyse neden kullanımı değil ? const countArray = countup(n - 1); countArray.push(n);constconstvar
YCode

1
@YCode no. kullandığınızda const countArray, bu olacak asla yeniden atanabilir. Üyelerini ve uzunluğunu değiştiren diziye yine de itebilirsiniz, ancak buna yeniden atama demiyoruz. Kullanmak constyerine letya varsen yeniden atama önlemek istediğinizde. Eğer BTW eğer do yeniden atama izin vermek istediğiniz, lethemen hemen her zaman daha iyi olduğunu var.
chharvey

@chharvey Teşekkürler! Yanıtınız beni "değere göre geçmeye ve referansa göre geçmeye", yeni bir konsepte ve garip bir fikre - değer değişikliğinin yeniden atanmasına - neden oldu. Daha fazla açıklamaya ihtiyaç duyan herkes cevapları burada kontrol etmelidir: stackoverflow.com/q/46131828/5965865
YCode

38

Önceki cevapları entegre etmek için, performans değişkeninin yanı sıra sabit değişkenleri bildirmenin belirgin bir avantajı vardır: yanlışlıkla kodda değiştirmeye veya yeniden beyan etmeye çalışırsanız, program sırasıyla değeri değiştirmez veya bir hata atmaz.

Örneğin, karşılaştırın:

// Will output 'SECRET'

const x = 'SECRET'
if (x = 'ANOTHER_SECRET') {  // Warning! assigning a value variable in an if condition
    console.log (x)
}

ile:

// Will output 'ANOTHER_SECRET'

var y = 'SECRET'
if (y = 'ANOTHER_SECRET') { 
    console.log (y)
}

veya

// Will throw TypeError: const 'x' has already been declared

const x = "SECRET"

/*  complex code */

var x = 0

ile

// Will reassign y and cause trouble

var y = "SECRET"

/*  complex code */

var y = 0

Bu "değişmez" davranışın yalnızca Dizeler, Temel Türler için geçerli olduğunu söylemelisiniz. Nesneleri, Dizileri vb. Kullanarak değerleri değiştirmek mümkündür, ancak yeni bir "Nesne" atamak mümkün değildir, örn. Const a = ["a", "b"]; a = []; bir hata atar aksi takdirde mümkündür
Fer To

Bir sabitin değerini de değiştirmeye çalıştığınız bir örneğiniz olmalıdır.
Joshua Pinter

Const kullanmak erişim değiştiricilere çok benzer, gerçek değişmezlik amaç değildir.
StingyJack

32

constolduğu değil değişmez.

Gönderen MDN'yi :

Sabit bildirimi bir değere salt okunur bir başvuru oluşturur. Sahip olduğu değerin değişmez olduğu anlamına gelmez, sadece değişken tanımlayıcısının yeniden atanamayacağı anlamına gelir.


24
Bu biraz yanıltıcı. Sayılar, dizgiler, boole vb. İçin (ilkel) constdeğişmez. Nesneler ve diziler için yeniden atanamaz, ancak içerik değiştirilebilir (örn. Array.push).
Florian Wendelborn

2
JS ilkelleri her zaman değişmezdir. Kullanıp kullanmamanız constbunu etkilemez.
12Me21

1
@Dodekeract bu nedenle tanım gereği değişmez değildir. Değerler değişebiliyorsa, değiştirilemez, ancak listelediğiniz ilkeller için değişmez olarak işlev görür
Anthony

13

var : Bir değişken, değer başlatma isteğe bağlı bildirin.

let : Blok kapsamı olan bir yerel değişken bildirin.

const : Salt okunur adlı bir sabit bildirin.

Ör:

var a;
a = 1;
a = 2;//re-initialize possible
var a = 3;//re-declare
console.log(a);//3

let b;
b = 5;
b = 6;//re-initiliaze possible
// let b = 7; //re-declare not possible
console.log(b);

// const c;
// c = 9;   //initialization and declaration at same place
const c = 9;
// const c = 9;// re-declare and initialization is not possible
console.log(c);//9
// NOTE: Constants can be declared with uppercase or lowercase, but a common
// convention is to use all-uppercase letters.

10

Harika cevaplarınız var, ama basit tutalım.

const tanımlanmış bir sabitiniz olduğunda kullanılmalıdır (şu şekilde okuyun: program yürütülürken değişmez).

Örneğin:

const pi = 3.1415926535

Bunun daha sonraki yürütmede değiştirilebilecek bir şey olduğunu düşünüyorsanız a kullanın var.

constÖrneğe dayanan pratik fark, sizinle birlikte her zaman pi'nin 3.14 olacağını kabul edeceğidir [...], bu bir gerçektir.

Bunu a olarak tanımlarsanız var, 3.14 [...] olabilir veya olmayabilir.

Daha teknik bir cevap için @Tibos akademik açıdan haklıdır.


7

Deneyimlerime göre const kullanıyorum sabit bir şekilde kodlanmış bitler örneğin bir dosya yolu veya sunucu adı arayan kod aramak zorunda kalmadan daha sonra değiştirmek isteyebileceğiniz bir şey ayarlamak istediğinizde .

Testinizdeki hata başka bir şey olsa da, x adlı başka bir değişken oluşturmayı düşünüyorsunuz, bu daha doğru bir test olacaktır.

const x = 'const';
x = 'not-const';

9
Ne demek istediğini anlıyorum, ama - senin için "sürekli" nin "değiştirmek isteyebileceğim şey" anlamına gelmesi komik. : P
Venryx

4

Kişisel tercih gerçekten. Dediğiniz gibi, yeniden atanmayacak ve sabit olduğunda const kullanabilirsiniz. Örneğin, doğum gününüzü atamak istiyorsanız. Doğum gününüz asla değişmez, böylece sabit olarak kullanabilirsiniz. Ama yaşınız değişiyor, bu bir değişken olabilir.


17
Bu çok uzun süren bir senaryo olurdu!
nullabilite

3
@ nullability Kaç kişinin yaşını izlediğinize bağlıdır. Birkaç düzineden fazla ve senaryo uzun süre çalıştırmak zorunda kalmayacak :).
Millie Smith

4

Özet:

const değişmez bir bağlayıcı oluşturur, yani const değişkeni tanımlayıcısı yeniden atanamaz.

const a = "value1";

ile yeniden atayamazsın

a = "value2";

Ancak, const tanımlayıcısı bir nesneyi veya diziyi barındırıyorsa, değerini yeniden atamadığımız sürece değiştirilebilir.

const x = { a: 1 }

x.a = 2; //is possible and allowed

const numbers = [1, 2];
numbers.push(3); //is possible and allowed

Lütfen not o const olan bir blok-kapsamlı tıpkı let aynı değildir var (fonksiyon-kapsamlı olan)

Şey olası değildir zaman Kısacası, yeniden atama yoluyla değişime kullanım const başka kullanım izin veya var sen istiyorum kapsamına bağlı olarak.

Yeniden tahsis yoluyla neyin değiştirilebileceği ve neyin yapılamayacağı aşikarsa, kod hakkında muhakeme yapmak çok daha kolaydır. Bir const bir izin değiştirmek için basit. Ve const varsayılan olarak bunu yapmadan önce iki kez düşünmenizi sağlar. Ve bu çoğu durumda iyi bir şeydir.



2
Main point is that how to decide which one identifier should be used during development.
In java-script here are three identifiers.

1. var (Can re-declared & re-initialize)
2. const (Can't re-declared & re-initialize, can update array values by using push)
3. let (Can re-initialize but can't re-declare)

'var': Kodlama standardından bahsederken kodlama sırasında genellikle diğer kullanıcı / geliştirici tarafından anlaşılması kolay olan tanımlayıcı adını kullanırız. Örneğin, bazı girdiler kullandığımız ve bunu işlediğimiz ve bir sonuç döndürdüğümüz birçok fonksiyon düşünüyoruz, örneğin:

**Example of variable use**

function firstFunction(input1,input2)
{
 var process = input1 + 2; 
 var result = process - input2;
 return result;
}


function otherFunction(input1,input2)
{
 var process = input1 + 8; 
 var result = process * input2;
 return result;
}

Yukarıdaki örneklerde her iki işlev de farklı değişkenler üreten ancak aynı isimde değişkenler kullanır. Burada 'süreç' ve 'sonuç'un her ikisinin de değişken olarak kullanıldığını görebiliriz ve olması gerekir.

 **Example of constant with variable**

 const tax = 10; 
 const pi = 3.1415926535; 

function firstFunction(input1,input2)
{
 var process = input1 + 2; 
 var result = process - input2;
 result = (result * tax)/100; 
 return result;
}


function otherFunction(input1,input2)
{
 var process = input1 + 8; 
 var result = process * input2 * pi;
 return result;
}

Java-komut dosyasında 'let' kullanmadan önce js dosyasının üstüne 'katı kullan' eklemeliyiz

 **Example of let with constant & variable**

 const tax = 10; 
 const pi = 3.1415926535; 
 let trackExecution = '';

function firstFunction(input1,input2)
{
 trackExecution += 'On firstFunction'; 
 var process = input1 + 2; 
 var result = process - input2;
 result = (result * tax)/100; 
 return result;
}


function otherFunction(input1,input2)
{
 trackExecution += 'On otherFunction'; # can add current time 
 var process = input1 + 8; 
 var result = process * input2 * pi;
 return result;
}

 firstFunction();
 otherFunction();
 console.log(trackExecution);

Yukarıdaki örnekte, belirli bir işlem sırasında hangi işlevlerin yerine getirildiğini ve hangi işlevlerin kullanılmadığını izleyebilirsiniz.


1

İlk olarak, üç yararlı şey const(paylaştığı kapsam iyileştirmeleri dışında let):

  • Kodu daha sonra okuyan insanlar için değerin değişmemesi gerektiğini belgeler.
  • Siz (veya sizden sonra gelen herkes) geri dönüp bildirimi bilerek değiştirmedikçe değeri değiştirmenizi önler.
  • Bu olabilir optimizasyonu açısından JavaScript motoru bazı analizler kaydedin. Örneğin, değerin değişemeyeceğini beyan ettiniz, bu nedenle motorun değerin değişip değişmediğini anlamak için iş yapması gerekmez, böylece değişmeyen değere göre optimizasyon yapılıp yapılmayacağına karar verebilir.

Sorularınız:

constYerinde ne zaman kullanılmalı var?

Sen olabilir Eğer değer hiç değişmez bir değişken bildiriyormuş her zaman yapmak. Uygun olduğunu düşünüp düşünmemek tamamen sizin tercihinize / ekibinizin tercihine bağlıdır.

Yeniden atanmayacak bir değişken her bildirildiğinde kullanılmalı mıdır?

Bu size / ekibinize bağlı.

Eğer var is used in place ofconst `veya tersi olursa aslında bir fark yaratır mı?

Evet:

  • varve constfarklı kapsam kurallarına sahipler. (Bunun letyerine karşılaştırmak isteyebilirsiniz var.) Özellikle: constve letblok kapsamlıdır ve global kapsamda kullanıldığında, global nesne üzerinde özellikler oluşturmazlar (globaller oluştursalar da). varglobal kapsama (global kapsamda kullanıldığında) veya fonksiyon kapsamına (bir blokta kullanılsa bile) sahiptir ve global kapsamda kullanıldığında global nesne üzerinde bir özellik oluşturur.
  • Yukarıdaki "üç yararlı şey" e bakın, hepsi bu soru için geçerlidir.

1

Anlamsallığı varvelet

varve letmakineye ve diğer programcılara bir ifadedir:

Bu ödevin değerinin yürütme süreci boyunca değişeceğini düşünüyorum. Bu ödevin nihai değerine güvenmeyin.

varVe kullanmanın etkilerilet

varve letdiğer programcıları deklarasyondan nihai kullanıma kadar tüm araya giren kodu ve programın yürütülmesinde o noktada ödevin değeri ile ilgili nedeni okumaya zorlar.

ESLint ve diğer dil hizmetlerinin, daha sonraki atamalarda yanlış yazılan değişken adlarını doğru bir şekilde algılamaları ve iç kapsamın bildirmeyi unuttuğu dış kapsam değişken adlarının kapsam yeniden kullanımını doğrulamak için makine mantığını zayıflatırlar.

Ayrıca, çalışma zamanlarının tüm kodyolları üzerinde, aslında, sabitler olduklarını, bunları optimize etmeden önce tespit etmek için birçok yinelemeyi çalıştırmasına neden olurlar. Her ne kadar bu hata algılama ve geliştirici anlaşılabilirliğinden daha az sorun olsa da.

Ne zaman kullanılır? const

Başvurunun değeri yürütme sırasında değişmezse, programcının amacını ifade etmek için doğru sözdizimi kullanılır const. Nesneler için, referansın değerini değiştirmek, referans değişmez olduğu için başka bir nesneyi işaret etmek anlamına gelir, ancak nesne değildir.

" const" nesneler

Nesne başvuruları için işaretçi başka bir nesneye değiştirilemez, ancak oluşturulan ve atanan nesne constbeyanı olduğunu değişken. constBaşvurulan bir diziye öğe ekleyebilir veya bu diziden öğe kaldırabilir ve constbaşvurulan bir nesneye özellik anahtarlarını değiştirebilirsiniz .

Değişmez nesnelere ulaşmak için (yine, kodunuzu insanlar ve makineler için akıl yürütmeyi kolaylaştırır), Object.freezenesneyi beyan / atama / oluşturmada şu şekilde yapabilirsiniz:

const Options = Object.freeze(['YES', 'NO'])

Object.freeze'in performans üzerinde bir etkisi vardır, ancak kodunuz muhtemelen başka nedenlerle yavaştır. Profil vermek istiyorsunuz.

Değişken nesneyi bir durum makinesinde kapsülleyebilir ve derin kopyaları değerler olarak döndürebilirsiniz (Redux ve React durumu bu şekilde çalışır). Bunu ilk ilkelerden nasıl oluşturacağınıza ilişkin bir örnek için bkz . Browser JS'de değiştirilebilir genel durumdan kaçınma .

Ne zaman varve letiyi bir eşleşme

letve vardeğişebilir durumu temsil eder. Bence sadece gerçek değişebilir durumu modellemek için kullanılmalıdırlar . " Bağlantı canlı mı? "

Bunlar en iyi şekilde , zamanın herhangi bir noktasında sabit olan ve kodunuzun geri kalanının gerçekte ne ile ilgilendiği " bağlantının mevcut durumunu " temsil eden sabit değerleri gösteren test edilebilir durum makinelerinde kapsüllenir .

Programlama, yan etkiler oluşturma ve veri dönüştürme ile yeterince zordur. Değişkenlerle değişebilir bir durum oluşturarak her işlevi denenemez bir durum makinesine dönüştürmek, sadece karmaşıklığı biriktirir.

Daha nüanslı bir açıklama için bkz . Mutant Shun - Davaconst .



0

JS derleme işinde uzman değilim, ama v8'in const bayrağından faydalandığını söylemek mantıklı

Normalde bir grup değişkeni bildirip değiştirdikten sonra, bellek parçalanır ve v8 yürütmeyi durdurur, gc veya çöp toplama yapmak için birkaç saniyelik bir duraklama yapar.

Bir değişkenin const v8 ile bildirilmesi durumunda, değişmeyeceği için diğer sabit değişkenler arasında sıkı bir sabit boyutlu kap içine koymaktan emin olabilirsiniz. Tür değişmeyeceğinden, bu veri türleri için uygun işlemleri de kaydedebilir.


0

O arasındaki kararına gelince let ve const , her zaman tercih const kullanım kodunda açıkça belirtecek şekilde. Bu şekilde, değişkeni yeniden bildirmeye çalışırsanız bir hata alırsınız. Başka bir seçenek yoksa, yeniden beyan etmek için izin verin . Olarak, unutmayın Anthony diyor, değerler (örnekler için, bir değişmez değildir const nesne özellikleri mutasyona uğramış olabilir).

O gelince var ES6 dışında olduğundan, ben üretim kodunda hiç kullanmamış ve bunun için bir kullanım durumunda düşünemiyorum. Ancak, var ile bildirilen değişkenlerin blok kapsamı olmadığına dikkat edin .

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.