Object.freeze () ve const


138

Object.freeze()constES6'da kullanmaya doğru geçiş için uygun bir yöntem gibi görünüyor .

Her ikisinin de kodda yer aldığı durumlar var mı yoksa değişmez verilerle çalışmanın tercih edilen bir yolu var mı?

Ben kullanmalıyım Object.freeze()ben desteğiyle çalışan tüm tarayıcılar ana kadar constsonra kullanmaya geçiş constyerine?


2
Derleme sürecimde babelj'leri kullanmaya başladım , böylece bunlar gibi uyumluluk sorunlarını çoğunlukla görmezden gelebilirim.
harcayan

22
Hayır - farklı şeyler yapıyorlar. const yeniden atamayı engeller (örn. x = 1; x = 2'yi sabitleyemezsiniz); donma, mutasyonu engeller (örneğin, Object.freeze (x); xa = 2);
joews

Bunu yeni bir soru haline getirmenin mi yoksa sadece buraya yapıştırmanın mantıklı olup olmadığından emin değilim, ancak Semboller ve Object.freeze arasında büyük farklar olup olmadığını da merak ediyorum. Onlar da (yani Semboller gelen dondurulmuş olarak değerlendirilmektedir ilişkilidir hissetmek Object.isFrozenama onlar da kendi ilkel veri tipi vardır ...)
Ağustos

1
Mutasyon sadece ilk seviye için engellenir, bu yüzden Object.freeze (x) yapamazsınız; xa = 2, ancak siz CAN Object.freeze (x); xab = 2. Bkz. jsfiddle.net/antimojv/op6ea91w/8 . Tam bir dondurma için geçici kitaplıkları kullanın
Antimo

Yanıtlar:


234

constve Object.freezetamamen farklı iki şeydir.

constbağlamalar ("değişkenler") için geçerlidir . Değişmez bir bağlanma yaratır, yani bağlamaya yeni bir değer atayamazsınız.

Object.freezedeğerler ve daha spesifik olarak nesne değerleri üzerinde çalışır . Bir nesneyi değişmez kılar, yani özelliklerini değiştiremezsiniz.


3
Temel olarak constyeni var; yalnızca blok kapsamlı ve yeniden atamayı engelliyor. Kullanabilirsiniz let, ancak gerçekten yalnızca bir değişkenin işaret ettiği değeri değiştirecekseniz bu, döngü kontrolü / yineleyici değişkenler ve sayılar ve dizeler gibi basit türler için anlamlıdır, ancak nesnelerin çoğu kullanımı için geçerli değildir ( dizileri). İçeriği değiştirilemeyen bir nesne / dizi istiyorsanız, onu bildirmenin yanı sıra onu constda çağırmalısınız Object.freeze().
Mark Reed

2
constYENİ değil var, letyenidirvar
Facundo Colombier

85

ES5'te Object.freeze, muhtemelen constnesnelerden daha yaygın olarak kullanılan ilkel öğeler üzerinde çalışmaz . ES6'da temelleri dondurabilirsiniz, ancak o zaman için de desteğiniz var const.

Öte yandan const, nesnelerin "dondurulmadığını" bildirmek için kullanılır, tüm nesneyi yeniden ifade edemezsiniz, ancak anahtarlarını serbestçe değiştirebilirsiniz. Öte yandan, donmuş nesneleri yeniden beyan edebilirsiniz.

Object.freeze aynı zamanda sığdır, bu nedenle onları korumak için iç içe geçmiş nesnelere yinelemeli olarak uygulamanız gerekir.

var ob1 = {
   foo : 1,
    bar : {
        value : 2   
    }
};
Object.freeze( ob1 );

const ob2 = {
   foo : 1,
    bar : {
        value : 2   
    }
}

ob1.foo = 4;  // (frozen) ob1.foo not modified
ob2.foo = 4;  // (const) ob2.foo modified

ob1.bar.value = 4;  // (frozen) modified, because ob1.bar is nested
ob2.bar.value = 4;  // (const) modified

ob1.bar = 4;  // (frozen) not modified, bar is a key of obj1
ob2.bar = 4;  // (const) modified

ob1 = {};  // (frozen) ob1 redeclared
ob2 = {}; // (const) ob2 not redeclared

Bu açıklama birçok sorumu tek bir taramada temizledi! İlgili ob1.bar.value = 4; // (frozen) modified, because ob1.bar is nested: Yöntemin kapsamı nedeniyle mi?
YCode

14

Özet:

constve Object.freeze()tamamen farklı amaçlara hizmet eder.

  • consthemen atanması gereken ve yeniden atanamayan bir değişkeni bildirmek için var mı? tarafından bildirilen değişkenler constblok kapsamlı olup, işlev kapsamlı değildir.var
  • Object.freeze()bir nesneyi kabul eden ve aynı nesneyi döndüren bir yöntemdir. Artık nesnenin hiçbir özelliği kaldırılamaz veya yeni özellikler eklenemez.

Örnekler const:

Örnek 1: Yeniden atanamıyor const

const foo = 5;

foo = 6;

Aşağıdaki kod, constanahtar kelime ile bildirilen foo değişkenini yeniden atamaya çalıştığımız için bir hata atar , onu yeniden atayamayız.

Örnek 2: Atanan veri yapıları constdeğiştirilebilir

const object = {
  prop1: 1,
  prop2: 2 
}

object.prop1 = 5;   // object is still mutable!
object.prop3 = 3;   // object is still mutable!

console.log(object);  // object is mutated

Bu örnekte, constanahtar kelimeyi kullanarak bir değişken tanımlıyoruz ve ona bir nesne atıyoruz . Object adlı bu değişkene yeniden atayamasak da, nesnenin kendisini değiştirebiliriz. Mevcut özellikleri değiştirirsek veya yeni özellikler eklersek, bunun etkisi olacaktır. İhtiyacımız olan nesnede herhangi bir değişikliği devre dışı bırakmak için Object.freeze().

Örnekler Object.freeze():

Örnek 1: Dondurulmuş bir nesneyi değiştiremezsiniz

object1 = {
  prop1: 1,
  prop2: 2
}

object2 = Object.freeze(object1);

console.log(object1 === object2); // both objects are refer to the same instance

object2.prop3 = 3; // no new property can be added, won't work

delete object2.prop1; // no property can be deleted, won't work

console.log(object2); // object unchanged

Bu örnekte çağırdığımızda Object.freeze()ve object1argüman olarak verdiğimizde , fonksiyon artık 'dondurulmuş' olan nesneyi döndürür. ===Operatörü kullanarak yeni nesnenin referansını eski nesneye karşılaştırırsak, aynı nesneye atıfta bulunduklarını görebiliriz. Ayrıca herhangi bir özelliği eklemeye veya kaldırmaya çalıştığımızda bunun herhangi bir etkisi olmadığını görebiliriz (katı modda hata atar).

Örnek 2: Referanslara sahip nesneler tam olarak dondurulmamış

const object = {
  prop1: 1,
  nestedObj: {
    nestedProp1: 1,
    nestedProp2: 2,
  } 
}


const frozen = Object.freeze(object);

frozen.prop1 = 5; // won't have any effect
frozen.nestedObj.nestedProp1 = 5; //will update because the nestedObject isn't frozen

console.log(frozen);

Bu örnek, yuvalanmış nesnelerin (ve diğer referans veri yapılarının) özelliklerinin hala değiştirilebilir olduğunu gösterir . Dolayısıyla Object.freeze(), referans olan özelliklere (örneğin Dizilere, Nesnelere) sahip olduğunda nesneyi tam olarak 'dondurmaz'.


12
var obj = {
  a: 1,
  b: 2
};
Object.freeze(obj);
obj.newField = 3; // You can't assign new field , or change current fields

Yukarıdaki örnek, nesnenizi tamamen değiştirilemez kılar.

Aşağıdaki örneğe bakalım.

const obj = {
  a: 1,
  b: 2
};
obj.a = 13; // You can change a field
obj.newField = 3; // You can assign new field.

Herhangi bir hata vermez.

Ama böyle denersen

const obj = {
      a: 1,
      b: 2
    };
obj = {
 t:4
};

"Obj salt okunur" gibi bir hata verir.

Başka bir kullanım durumu

const obj = {a:1};
var obj = 3;

Atacak Duplicate declaration "obj"

Ayrıca mozilla docs const açıklamasına göre

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

Bu örnekler babeljs ES6 özelliklerine göre oluşturulmuştur.


4

Basit olalım.

Onlar farklı. Her durumu açıklayacak olan koddaki yorumları kontrol edin.

Const- letHangi değerin yeniden atanamayacağı, yeniden bildirilmiş gibi blok kapsam değişkenidir .

Bunun anlamı

{
 const val = 10;  // you can not access it outside this block, block scope variable

}

console.log(val); // undefined because it is block scope 

const constvalue = 1;
constvalue = 2; // will give error as we are re-assigning the value;
const obj = { a:1 , b:2};

obj.a = 3;
obj.c = 4;
console.log(obj); // obj = {a:3,b:2,c:4} we are not assigning the value of identifier we can 
                  // change the object properties, const applied only on value, not with properties
obj = {x:1};     // error you are re-assigning the value of constant obj 
obj.a = 2 ;     // you can add, delete element of object

Bütün anlayış, const'ın blok kapsamı olduğu ve değerinin yeniden atanmadığıdır.

Object.freeze: Nesne kök özellikleri değiştirilemez, ayrıca daha fazla özellik ekleyip silemeyiz ancak tüm nesneyi yeniden atayabiliriz.

var x = Object.freeze({data:1,
    name:{
    firstname:"hero", lastname:"nolast"
    }
});

x.data = 12;  // the object properties can not be change but in const you can do
x.firstname ="adasd"; // you can not add new properties to object but in const you can do

x.name.firstname = "dashdjkha"; // The nested value are changeable 

//The thing you can do in Object.freeze but not in const

x = { a: 1};  // you can reassign the object when it is Object.freeze but const its not allowed

// Her ikisinde de benzer olan bir şey, yuvalanmış nesnelerin değiştirilebilir olmasıdır

const obj1 = {nested :{a:10}};
var obj2 =  Object.freeze({nested :{a:10}});

obj1.nested.a = 20; // both statement works
obj2.nested.a = 20;

Teşekkürler.

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.