Object.freeze() против const

Object.freeze() похоже на переходный удобный метод для перехода к использованию const в ES6.

Есть ли случаи, когда оба занимают свое место в коде, или есть предпочтительный способ работы с неизменяемыми данными?

Должен ли я использовать Object.freeze() до того момента все браузеры работаю с поддержкой const затем переключитесь на использование const вместо?

4 ответа

Решение

const а также Object.freeze это две совершенно разные вещи.

const применяется к привязкам ("переменным"). Он создает неизменную привязку, т. Е. Вы не можете присвоить привязке новое значение.

Object.freeze работает со значениями, а более конкретно - со значениями объектов. Это делает объект неизменным, то есть вы не можете изменить его свойства.

В ES5 Object.freeze не работает на примитивах, которые, вероятно, будут чаще объявляться с использованием const чем объекты. Вы можете заморозить примитивы в ES6, но тогда у вас также есть поддержка const,

С другой стороны const используемый для объявления объектов не "замораживает" их, вы просто не можете повторно объявить весь объект, но вы можете свободно изменять его ключи. С другой стороны, вы можете переопределить замороженные объекты.

Object.freeze также мелкий, поэтому вам нужно будет рекурсивно применить его к вложенным объектам, чтобы защитить их.

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

Резюме:

const а также Object.freeze() служить совершенно другим целям.

  • const предназначен для объявления переменной, которая должна быть задана сразу и не может быть переназначена. переменные, объявленные const являются областью действия блока, а не функцией, как переменные, объявленные с var
  • Object.freeze() это метод, который принимает объект и возвращает тот же объект. Теперь объект не может удалить ни одного из своих свойств или добавить какие-либо новые свойства.

Примеры const:

Пример 1. Не могу переназначить const

const foo = 5;

foo = 6;

Следующий код выдает ошибку, потому что мы пытаемся переназначить переменную foo, которая была объявлена ​​с const Ключевое слово, мы не можем переназначить его.

Пример 2: структуры данных, которые назначены const могут быть видоизменены

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

В этом примере мы объявляем переменную, используя const Ключевое слово и назначить ему объект. Хотя мы не можем переназначить эту переменную с именем object, мы можем изменить сам объект. Если мы изменим существующие свойства или добавим новые, это будет иметь эффект. Чтобы отключить любые изменения объекта, нам нужно Object.freeze(),

Примеры Object.freeze():

Пример 1: Невозможно изменить замороженный объект

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

В этом примере, когда мы вызываем Object.freeze() и дать object1 в качестве аргумента функция возвращает объект, который теперь "заморожен". Если мы сравним ссылку нового объекта со старым объектом, используя === Оператор мы можем наблюдать, что они относятся к одному и тому же объекту. Также, когда мы пытаемся добавить или удалить какие-либо свойства, мы видим, что это не имеет никакого эффекта (будет выдавать ошибку в строгом режиме).

Пример 2: объекты со ссылками не полностью заморожены

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

Этот пример показывает, что свойства вложенных объектов (и других по ссылочным структурам данных) по- прежнему изменчивы. Так Object.freeze() не полностью "замораживает" объект, когда у него есть свойства, которые являются ссылками (например, массивы, объекты).

Пусть будет просто.

Они разные. Проверьте комментарии к коду, которые объяснят каждый случай.

Const - это переменная области видимости блока, например let, значение которой не может быть переназначено, повторно объявлено.

Это означает

{
 const val = 10;  // you can not access it out side 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 reassigning 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 reassigning the value of constant obj 
obj.a = 2 ;     // you can add ,delete element of object

Полное понимание состоит в том, что const является областью действия блока, и его значение не переназначается.

Object.freeze: корневые свойства объекта неизменны, также мы не можем добавлять и удалять дополнительные свойства, но мы можем переназначить весь объект снова.

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

// Одна вещь, которая похожа в обоих случаях, это то, что вложенные объекты являются изменяемыми

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

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

Благодарю.

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

Приведенный выше пример полностью делает ваш объект неизменным.

Давайте посмотрим следующий пример.

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

Это не даст никакой ошибки.

Но если вы попробуете так

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

Это выдаст ошибку вроде "obj только для чтения".

Другой вариант использования

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

Это бросит Duplicate declaration "obj"

Также согласно объяснениям Mozilla Docs Const

Объявление const создает доступную только для чтения ссылку на значение. Это не означает, что значение, которое оно содержит, является неизменным, только то, что идентификатор переменной не может быть переназначен.

Эти примеры созданы в соответствии с возможностями babeljs ES6.

Другие вопросы по тегам