loading...

Constants are not really constants

aminnairi profile image Amin Updated on ・3 min read

Ever used the const keyword? If not, it allows you to define variables that cannot be re-assigned.

"use strict";

const fruit = "orange";

fruit = "apple";
// TypeError: invalid assignment to const `fruit'

Try it online.

They have also the advantage to being block-scoped. But that is not the point of this post. You can find more about the const keyword here.

We can define constants for about any variables in our code.

"use strict";

const answer = 42;
const awesome = true;

answer = 41;
// TypeError: Assignment to constant variable.

awesome = false;

Try it online.

An apple a day, keeps the exceptions away...

But now you are more experienced with constants and you want to apply this pattern to more complex variables like arrays and objects because you are now convinced that immutable variables are a good way to prevent errors and side-effects in your code.

"use strict";

const fruits = [
  "apple",
  "banana",
  "lemon",
  "orange"
];

fruits[0] = "salad";
// ... 

Try it online.

If you run this code, you'll notice that no errors are thrown. There is nothing wrong with this code and it is not acting weird. In fact, it is acting exactly the way it has been designed: the const keyword only prevents re-assignement. Remember the error message above? So this means that the previous code will work, while this code wont:

"use strict";

const fruits = [
  "apple",
  "banana",
  "lemon",
  "orange"
];

fruits = [
  "salad",
  "carrot",
  "cucumber",
  "potato"
];
// TypeError: Assignment to constant variable.

Try it online.

Now we have our exception thrown! But what we wanted was a true constant variable, capable of warning us when we try to re-assign it as well as when we try to change its members. There is a solution in JavaScript that is the Object.freeze method.

"use strict";

const fruits = Object.freeze([
  "apple",
  "banana",
  "lemon",
  "orange"
]);

fruits[0] = "salad";
// TypeError: Cannot assign to read only property '0' of object '[object Array]'

Try it online.

Cool! Now our object is in read-only mode and cannot be overwritten. And what if we try to add values to our array?

"use strict";

const fruits = Object.freeze([
  "apple",
  "banana",
  "lemon",
  "orange"
]);

fruits.push("salad");
// TypeError: Cannot add property 4, object is not extensible

Try it online.

Yay! Working as we expect it to be.

Honey, guests are coming!

Now, a little more complex example. Let's say that we want to have an object with some sort of configuration for a recipe. The properties will be the ingredients, and the values will be the dosage.

"use strict";

const classicPasta = Object.freeze({
  pasta: "500g",
  salt: "1tbs",
  pepper: "1tbs"
});

classicPasta.pepper = "11tbs";
// TypeError: Cannot assign to read only property 'pepper' of object '#<Object>'

Try it online.

Whoa! We almost failed this recipe. Guest are testing our pastas. They love them. Congratulations this dinner is a success! But now you are gaining visibility in your country. Unknown guests wants to taste your awesome recipe. Quick! Let's increase the dosage... But wait, our object is frozen. You can't. They were coming from far away... They now hate you. This is no good! We must find a solution. This solution is Object.seal. This will lock our object, preventing any new properties from being added but allowing us to update our object when needed.

"use strict";

const classicPasta = Object.seal({
  pasta: "500g",
  salt: "1tbs",
  pepper: "1tbs"
});

classicPasta.pasta = "2.5kg";
classicPasta.salt = "10tbs";
classicPasta.pepper = "10tbs";

classicPasta.sugar = "1tbs";
// TypeError: Cannot add property sugar, object is not extensible

Try it online.

Wonderful! Your guests are coming. They love it again... Another win for PastaScript!

Conclusion

Forget all cooking books and learn JavaScript. But try not to abuse the pepper or salt in your pasta. It can be harmful for your heart. Don't forget to drink some water from time to time and exercise!

Posted on by:

Discussion

pic
Editor guide
 

What name do you think would be appropriate for const as they are in javascript since they are not really constants?

 

That's an interesting question. Thanks for asking!

In my opinion, I don't think that we should rename the keyword, but instead change the behavior of this keyword for objects and arrays especially.

That would make more sense to me. What do you think?

 

I agree that changing the behaviour makes sense. But what if we wanted to maintain the behaviour, what name could we give to that behaviour. cannot reassign but can modify.

We could follow the path taken by Elm and their awesome error messages like:

I saw you used a constant here:

const fruits = [...];
      ^
      |
     here

It seems like you tried to update one of its member:

fruits[0] = ...
       ^
       |
      here

I think that you might wanna use Object.freeze to prevent causing side effects

const fruits = Object.freeze([...]);