Anahtar kelime 'sabit', değeri değiştirilemez yapmaz. Bunun anlamı ne?


85

Orada const tanımı içinde ES6 keşfetmek Dr Axel Rauschmayer tarafından:

constlet gibi çalışır, ancak bildirdiğiniz değişken daha sonra değiştirilemeyen bir değerle hemen başlatılmalıdır . […]

const bar = 123;
bar = 456;  // TypeError: `bar` is read-only

ve sonra yazıyor

Tuzak: Sabit, değeri değişmez kılmaz

const yalnızca bir değişkenin her zaman aynı değere sahip olduğu anlamına gelir, ancak değerin kendisinin değişmez olduğu veya değişmez olduğu anlamına gelmez.

Bu tuzağa biraz karıştım. Herhangi biri constbu tuzağı açıkça tanımlayabilir mi?


38
MDN açıklama net: "const bildirimi bir değere salt okunur bir referansı oluşturan O tutan değer değişken tanımlayıcı atanamaz sadece, değişmez olduğu anlamına gelmez Örneğin, söz konusu içerik bir olduğunu.. Nesne , bu, nesnenin kendisinin hala değiştirilebileceği anlamına gelir . " (benim vurgu)
Gerardo Furtado

4
Bu, değerin değiştirilebilir olması durumunda (örneğin, bir nesneyse), o nesneyi yine de değiştirebileceğiniz anlamına gelir (örneğin, özellikleri güncelle, ekle, kaldır).
Felix Kling

2
const x = "immutable"değişmezdir, çünkü Stringdeğişmezdir. constyalnızca yeniden atamayı yasaklar.

3
@ibrahimmahrir: geçen bir referans (JavaScript nesneleri için ne) geçişte aynı değildir ile (değer önemsizdir bağları arasındaki ilişkiyi tarif eder) referans.
Felix Kling

2
@ibrahimmahrir: Evet, sorun bu. Referansla geçiş teriminin çok özel bir anlamı vardır .
Felix Kling

Yanıtlar:


97

MDN bunu güzel bir şekilde özetliyor:

Const bildirimi, bir değere salt okunur bir başvuru oluşturur. Bu, tuttuğ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. Örneğin, içeriğin bir nesne olması durumunda, bu, nesnenin kendisinin hala değiştirilebileceği anlamına gelir.

Daha kısaca: const değişmez bir bağlama oluşturur.

Başka bir deyişle: const, var gibi, size bir şeyler depoladığınız değiştirilebilir bir bellek parçası verir. Bununla birlikte, const, aynı bellek parçasına başvurmaya devam etmeniz gerektiğini belirtir - değişkeni farklı bir bellek öbeğine yeniden atayamazsınız çünkü değişken başvurusu sabittir.

Bir şeyi ilan ettikten sonra gerçekten sabit ve değişmeyen yapmak için, gibi bir şey kullanmanız gerekir Object.freeze(). Ancak, bu sığdır ve yalnızca anahtar / değer çiftlerinde çalışır. Tüm bir nesneyi dondurmak biraz daha fazla çaba gerektirir. Bunu performansa dayalı bir şekilde defalarca yapmak daha da zordur. Buna gerçekten ihtiyacınız varsa, Immutable.js gibi bir şeye bakmanızı tavsiye ederim.


20
C açısından: Eğer normal var xbir struct Object *xa const xise , a a'dır struct Object *const x. İşaretçi değiştirilemez; can'a işaret ettiği şey.
Fund Monica'nın Davası

151

constJavaScript'te bir şey yaptığınızda, değişkeni başka bir şeye başvurmak için yeniden atayamazsınız. Bununla birlikte, değişken yine de değiştirilebilir bir nesneye başvurabilir.

const x = {a: 123};

// This is not allowed.  This would reassign `x` itself to refer to a
// different object.
x = {b: 456};

// This, however, is allowed.  This would mutate the object `x` refers to,
// but `x` itself hasn't been reassigned to refer to something else.
x.a = 456;

Dizeler ve sayılar gibi ilkel constifadeler söz konusu olduğunda, değerleri değiştirmediğiniz için bunun yerine değişkene yeni bir değer atadığınız için anlaşılması daha kolaydır.


18
Bu cevap, kabul edilenden çok daha iyidir. Daha kısa ve öz ve gerçek örnek kod içerir. (Başka bir deyişle, noktaya
varıyor

16

Yeniden bağlama

constve letbildirimler, tanımlayıcılar ve değerler arasındaki yeniden bağlantılara (diğer bir deyişle yeniden atamalara) izin verilip verilmediğini kontrol eder:

const x = "initial value";
let y = "initial value";

// rebinding/reassignment

try { x = "reassignment" } catch(e) { console.log(x) } // fails

y = "reassignment"; // succeeds
console.log(y);

Değişmezlik

Değişmezlik, tür düzeyinde kontrol edilir. Objectdeğişebilir bir tür, oysa Stringdeğişmez bir tür:

const o = {mutable: true};
const x = "immutable";

// mutations

o.foo = true; // succeeds
x[0] = "I"; // fails

console.log(o); // {mutable: true, foo: true}
console.log(x); // immutable


1

const şu anlama gelir: Başlangıçta atanan değeri değiştiremezsiniz.

İlk olarak, js'de bir değerin ne olduğunu tanımlayın . Değer şunlar olabilir: Boole'lar, dizeler, sayılar, nesneler, işlevler ve tanımlanmamış değerler.

Mesela: İnsanlar sizi isminizle arıyor, değişmiyor. Ancak kıyafetlerini değiştirirsin. Bağlayıcı insanlar arasında ve size adıdır. Gerisi değişebilir. Garip örnek için üzgünüm.

Öyleyse size bazı örnekler vereyim:

// boolean
const isItOn = true;
isItOn = false;           // error

// number
const counter = 0;
counter++;                // error

// string
const name = 'edison';
name = 'tesla';           // error

// objects
const fullname = {
  name: 'albert',
  lastname: 'einstein'
};

fullname = {              // error
  name: 'werner',
  lastname: 'heisenberg'
};
// NOW LOOK AT THIS:
//
// works because, you didn't change the "value" of fullname
// you changed the value inside of it!
fullname.name = 'hermann';

const increase = aNumber => ++aNumber;
increase = aNumber => aNumber + 1;      // error

// NOW LOOK AT THIS:
//
// no error because now you're not changing the value
// which is the decrease function itself. function is a
// value too.
let anotherNumber = 3;
const decrease = () => --anotherNumber;

anotherNumber = 10;             // no error
decrease();                     // outputs 9

const chaos = undefined;
chaos = 'let there be light'    // error

const weird = NaN;
weird = 0                       // error

Gördüğünüz gibi, "ilk" atanan değeri sabit olarak değiştirmediğiniz sürece , hata yok. İlk atanan değeri başka bir şeye değiştirmeye çalıştığınızda sinirlenir ve hata verir.

Yani, kullanırken bildiğiniz ikinci şey budur const. Yani, beyanında bir değere başlanmalıdır, yoksa sinirlenir.

const orphan;                    // error
const rich = 0;                  // no error

0

ES6/ ES2015 constanahtar kelime:

constAnahtar ile (ilan gibi bir blok kapsamına sahip değişken bildirmek için kullanılır let). Bir değişken ilan arasındaki fark constve letşu şekildedir:

  1. Tanımlanan bir değişken constolamaz yeniden .
  2. İle tanımlanan bir değişken constolması gerekir atanmış zaman ilan . Bu, önceki noktanın mantıksal bir sonucudur çünkü ile bildirilen bir değişken constyeniden atanamaz, bu yüzden değişkeni tanımladığımızda onu tam olarak bir kez atamamız gerekir .

Misal:

// we declare variable myVariable
let myVariable;

// first assignment
myVariable = 'First assingment';
// additional assignment
myVariable = 'Second assignment';

// we have to declare AND initialize the variable at the same time
const myConstant = 3.14;

// This will throw an error
myConstant = 12;

Yukarıdaki örnekte şunları gözlemleyebiliriz:

  1. İle myVariablebildirilen değişken letönce bildirilebilir ve sonra atanabilir.
  2. İle myConstantbildirilen değişken constaynı anda bildirilmeli ve atanmalıdır.
  3. Değişkeni yeniden atamaya çalıştığımızda myConstantaşağıdaki hatayı alıyoruz:

Yakalanmamış TypeError: Sabit değişkene atama

Uyarı: ile atanan değişken consthala değiştirilebilir:

İle bildirilen bir değişken constyeniden atanamaz, yine de değiştirilebilir . constDeğişken olmak, değişkene atanan veri yapısının (nesne, dizi, harita vb.) Hala değiştirilebileceği (yani mutasyona uğrayabileceği) anlamına gelir. Mutasyon örnekleri:

  1. Bir nesnenin bir özelliğini ekleme / silme / değiştirme
  2. Belirli bir dizi dizininde bir dizinin değerini değiştirme

Bir nesnenin gerçekten değişken olmasını istiyorsanız, gibi bir şey kullanmanız gerekecek Object.freeze(). Bu, bir nesneyi donduran bir yöntemdir. Dondurulmuş bir nesne artık değiştirilemez ve yeni özellikler eklenemez.

Misal:

const obj = {prop1: 1};

obj.prop1 = 2;
obj.prop2 = 2;

console.log(obj);

// We freeze the object here
Object.freeze(obj);

obj.prop1 = 5;
delete obj.prop2;

// The object was frozen and thus not mutated
console.log(obj);

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.