Object.freeze () vs const

136

Object.freeze()Sepertinya metode kenyamanan transisi untuk bergerak menggunakan constES6.

Apakah ada kasus di mana keduanya mengambil tempat dalam kode atau apakah ada cara yang disukai untuk bekerja dengan data yang tidak dapat diubah?

Haruskah saya menggunakan Object.freeze()sampai saat ini semua browser saya bekerja dengan dukungan constkemudian beralih menggunakan const?

Sergei Basharov
sumber
2
Saya telah menggunakan babeljs dalam proses build saya sehingga saya bisa mengabaikan masalah kompatibilitas seperti ini.
pemboros
22
Tidak - mereka melakukan hal yang berbeda. const mencegah penugasan kembali (mis. Anda tidak dapat const x = 1; x = 2); membekukan mencegah mutasi (misalnya Anda tidak bisa Object.freeze (x); xa = 2);
joews
Tidak yakin apakah masuk akal untuk membuat ini pertanyaan baru atau hanya menempelkannya di sini, tetapi saya juga ingin tahu apakah ada perbedaan besar antara Simbol dan Object.freeze? Saya merasa mereka juga terkait (yaitu Simbol dievaluasi sebagai beku dari Object.isFrozentetapi mereka juga tipe data primitif mereka sendiri ...)
Agustus
1
Mutasi dicegah hanya untuk level pertama sehingga Anda tidak bisa Object.freeze (x); xa = 2, tetapi Anda BISA Object.freeze (x); xab = 2. Lihat jsfiddle.net/antimojv/op6ea91w/8 . Untuk pembekuan penuh gunakan perpustakaan ad hoc
Antimo

Jawaban:

232

constdan Object.freezedua hal yang sangat berbeda.

constberlaku untuk binding ("variabel"). Ini menciptakan pengikatan yang tidak dapat diubah, yaitu Anda tidak dapat menetapkan nilai baru untuk pengikatan.

Object.freezebekerja pada nilai , dan lebih khusus lagi, nilai objek . Itu membuat objek tidak berubah, yaitu Anda tidak dapat mengubah propertinya.

Felix Kling
sumber
3
Pada dasarnya, constini adalah yang baru var; itu hanya dicekal dan mencegah penugasan kembali. Anda dapat menggunakan let, tetapi benar-benar hanya perlu jika Anda akan mengubah nilai yang ditunjuk suatu variabel, yang masuk akal untuk variabel kontrol loop / iterator dan tipe sederhana seperti angka dan string, tetapi tidak untuk sebagian besar penggunaan objek (termasuk array). Jika Anda menginginkan objek / array yang isinya tidak dapat diubah, maka selain menyatakannya, constAnda juga harus memanggilnya Object.freeze().
Mark Reed
2
constBUKAN yang baru var, letadalah yang baruvar
Facundo Colombier
84

Dalam ES5 Object.freezetidak bekerja pada primitif, yang mungkin akan lebih sering dinyatakan menggunakan constobjek. Anda dapat membekukan primitif di ES6, tetapi kemudian Anda juga memiliki dukungan untuk const.

Di sisi lain yang constdigunakan untuk mendeklarasikan objek tidak "membekukan" mereka, Anda tidak bisa mendeklarasikan ulang seluruh objek, tetapi Anda dapat memodifikasi kuncinya secara bebas. Di sisi lain Anda dapat mendeklarasikan ulang objek yang beku.

Object.freeze juga dangkal, jadi Anda harus menerapkannya secara rekursif pada objek bersarang untuk melindunginya.

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
pawel
sumber
Penjelasan ini membersihkan begitu banyak pertanyaan saya dalam satu sapuan! Mengenai ob1.bar.value = 4; // (frozen) modified, because ob1.bar is nested: Apakah karena ruang lingkup metode ini?
YCode
14

Ringkasan:

constdan Object.freeze()melayani tujuan yang sama sekali berbeda.

  • constada untuk mendeklarasikan variabel yang harus ditanggapi segera dan tidak dapat dipindahkan. variabel yang dideklarasikan oleh constadalah scoped blok dan bukan fungsi scoped seperti variabel yang dideklarasikan denganvar
  • Object.freeze()adalah metode yang menerima objek dan mengembalikan objek yang sama. Sekarang objek tidak dapat menghapus semua propertinya atau properti baru apa pun yang ditambahkan.

Contoh const:

Contoh 1: Tidak dapat menetapkan ulang const

const foo = 5;

foo = 6;

Kode berikut memunculkan kesalahan karena kami mencoba menetapkan ulang variabel foo yang dideklarasikan dengan constkata kunci, kami tidak dapat menetapkannya kembali.

Contoh 2: Struktur data yang ditugaskan untuk constdapat dimutasi

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

Dalam contoh ini kita mendeklarasikan variabel menggunakan constkata kunci dan menetapkan objek untuk itu. Meskipun kami tidak dapat menetapkan kembali objek yang disebut variabel ini, kami dapat mengubah objek itu sendiri. Jika kami mengubah properti yang ada atau menambahkan properti baru, ini akan berpengaruh. Untuk menonaktifkan segala perubahan pada objek yang kita butuhkan Object.freeze().

Contoh Object.freeze():

Contoh 1: Tidak dapat bermutasi objek beku

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

Dalam contoh ini ketika kita memanggil Object.freeze()dan memberikan object1sebagai argumen, fungsi mengembalikan objek yang sekarang 'beku'. Jika kita membandingkan referensi objek baru ke objek lama menggunakan ===operator, kita dapat mengamati bahwa mereka merujuk ke objek yang sama. Juga ketika kita mencoba untuk menambah atau menghapus properti apa pun kita dapat melihat bahwa ini tidak memiliki efek apa pun (akan melempar kesalahan dalam mode ketat).

Contoh 2: Objek dengan referensi tidak sepenuhnya dibekukan

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);

Contoh ini menunjukkan bahwa properti objek bersarang (dan lainnya dengan struktur data referensi) masih bisa berubah . Jadi Object.freeze()tidak sepenuhnya 'membekukan' objek ketika memiliki properti yang merupakan referensi (misalnya Array, Objek).

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

Contoh di atas benar-benar membuat objek Anda tidak berubah.

Mari kita lihat contoh berikut.

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

Itu tidak akan memberikan kesalahan.

Tetapi jika Anda mencoba seperti itu

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

Ini akan melempar kesalahan seperti itu "obj read-only".

Kasus penggunaan lain

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

Itu akan melempar Duplicate declaration "obj"

Juga menurut penjelasan const const mozilla

Deklarasi const menciptakan referensi read-only ke suatu nilai. Itu tidak berarti nilai yang dipegangnya tidak berubah , semata-mata bahwa pengenal variabel tidak dapat dipindahkan.

Contoh-contoh ini dibuat sesuai dengan fitur babeljs ES6.

İlker Korkut
sumber
4

Biar sederhana.

Mereka berbeda. Periksa komentar pada kode, yang akan menjelaskan setiap kasus.

Const- Ini adalah variabel lingkup blok seperti let, yang nilainya tidak dapat dipindahkan, dinyatakan kembali.

Itu berarti

{
 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

Pemahaman keseluruhan adalah bahwa const adalah lingkup blok dan nilainya tidak ditugaskan kembali.

Object.freeze: Properti root objek tidak dapat diubah, juga kita tidak dapat menambah dan menghapus lebih banyak properti tetapi kita dapat menugaskan kembali seluruh objek.

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

// Satu hal yang serupa di keduanya adalah, objek bersarang bisa berubah

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

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

Terima kasih.

Himanshu sharma
sumber