13

I have a routine where I receive some data from an api. I'd like to store this data in an object, but after that i want to "lock" this object and not allow any change to the properties or their values after that point. Is that possible? (If possible using only ES5).

2
  • you mean like const Commented Oct 20, 2017 at 16:22
  • 1
    @palaѕн OP wants to keep it ES5 only Commented Oct 20, 2017 at 16:24

6 Answers 6

26

If you wish for an object to not be able to be modified you can use Object.freeze.

The Object.freeze() method freezes an object: that is, prevents new properties from being added to it; prevents existing properties from being removed; and prevents existing properties, or their enumerability, configurability, or writability, from being changed, it also prevents the prototype from being changed. The method returns the object in a frozen state.

If you simply want to prevent a variable from being reassigned you can use const (ES6), however note that:

The const declaration creates a read-only reference to a value. It does not mean the value it holds is immutable, just that the variable identifier cannot be reassigned.

E.g, the following is perfectly valid

const a = { x: 7 }
a.x = 9
console.log(a.x) // 9

However, trying to reassign a variable declared with const will throw a TypeError:

const a = 5
a = 7

Sign up to request clarification or add additional context in comments.

7 Comments

This won't prevent you from re-assigning a different value to a var.
technically the const variable is not mutable. It's const. The object the variable is referencing is mutable but the variable is not and can not be changed to reference a different object.
Object.freeze was kinda good enough, but i fell into a different problem: Before freezing my object i assign those values to a different var and then freeze the original var. When i tried to remove itens from the second var(not freezed) it raised this error (angular.js:13294 TypeError: Cannot add/remove sealed array elements at Array.splice (<anonymous>))
Thats probably due to those vars referencing the same memory space. Any idea on that second issue (Guess i should open a new question)
@ArunkumarSrisailapathi, correct. You’d have to do this for the nested objects as well
|
6

For Immutable object we can use below approches

  1. Object.freeze()
  2. To enforce object immutability while update the object make sure to
  3. use Object.assign({},a,{foo:'bar'}) rather than a.foo='bar'
  4. we can use spread(...) operator.

See example:

var person={name:'pavan',age:26}

var newPerson={...person,name:'raju'}

console.log(newPerson ===person) //false
console.log(person)  //{name:'pavan',age:26}
console.log(newPerson)  //{name:'raju',age:26}

Comments

1

No. There's no good way to enforce const-ness is ES5.

3 Comments

Not sure why you'd think Object.freeze from ES5 is not a good solution to the OP's question. The OP said they wanted the object locked down and said nothing about reassigning a variable, which is all that const does. I reread the OP's question several times and think freezing it is exactly what they have in mind. Cheers.
@RayToal If you look at the edit history of the question, you'll see that the version that I answered asked: "Id'like to store this data in a var, but after that i want to "lock" this var". A subsequent edit changed the meaning of the OP's question and invalidated the answer.
Oh dear thank you I did not see that the question was edited. Locking a var is certainly different that making the object immutable
1

You can use Object.freeze() method which freezes an object. A frozen object can no longer be changed and prevents :

  • New properties from being added to it
  • Existing properties from being removed
  • Changing the enumerability, configurability, or writability of existing properties
  • The values of existing properties from being changed.

Demo :

const obj = {
  name: 'Alpha',
  age: 30,
  hobbies: ['reading', 'writing']
};

Object.freeze(obj);

obj.name = 'Beta';
obj.hobbies[0] = 'painting'; 

console.log(obj.name); // Alpha (It works fine with the properties which contains primitive values)
console.log(obj.hobbies[0]); // painting (It does not work for nested objects/array)

If you see in above code snippet, It works fine with the properties which contains primitive values but it is updating the values of nested object/array.

Hence, You can try as const If you are working with typescript in your requirement. It will freeze the whole object along with the nested properties with object/array.

Comments

1

If you separate you code into pure and impure parts (as with functional core, imperative shell), you can get by in the pure parts using objects and arrays and not, as a matter of discipline, mutating them.

I've done this for years and have a library which aids this style of development. I can't imagine needing the insurance policy of having to Object.freeze everything. Now, eventually, when records and tuples is adopted into the spec you can just use them instead!

Comments

0

You can use Object.freeze() + get method (accessor properties)

const obj = {
  label: 'Jim',
  leisures: ['gaming', 'work out'],
  get toys(){
    return ['ball', 'car']
  },
};

Object.freeze(obj);

obj.label = 'Dwight'; // immutable
obj.leisures[0] = 'coding';  // mutable
obj.toys[0] = 'axe';  // immutable

console.log(obj.label); // Jim 
console.log(obj.leisures[0]); // coding 
console.log(obj.toys[0]); // ball, because the `get` method makes toys() accesible, but isnt mutable. 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.