Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

const Versus let

Keep on Learning!

If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

Start your All-Access Pass
Buy just this tutorial for $12.00

The ECMAScript gods didn't stop with let - they added a third way to declare a new variable: var, let and cat. Wait, that's not right - var, let and const.

Back in our play file, remove the log and initialize the variable with const:

12 lines play.js
const aGreatNumber = 10;
if (true) {
aGreatNumber = 42;
}
... lines 6 - 12

As you're probably already guessing - and as you can see from PhpStorm being very angry - when you initialize a variable with const, it can't be reassigned.

When we try this now, we get a huge error!

TypeError: Assignment to constant variable.

But if we comment-out the line where we change the variable, it works just like we expect:

12 lines play.js
const aGreatNumber = 10;
if (true) {
//aGreatNumber = 42;
}
... lines 6 - 12

As far as scope goes, const and let work the same. So really, const and let are identical... except that you can't modify a const variable.

You can Change a const?

Well actually, that's not completely accurate. Create another const variable called aGreatObject. Inside it, set withGreatKeys to true. Below, change that object: aGreatObject.withGreatKeys = false:

16 lines play.js
const aGreatNumber = 10;
const aGreatObject = { withGreatKeys: true };
aGreatObject.withGreatKeys = false;
... lines 5 - 16

Log that object at the bottom:

16 lines play.js
const aGreatNumber = 10;
const aGreatObject = { withGreatKeys: true };
aGreatObject.withGreatKeys = false;
... lines 5 - 9
setTimeout(() => {
console.log(aGreatNumber);
console.log(aGreatObject)
}, 1000);
... lines 14 - 16

Will this work?

Try it! It does work! The withGreatKeys property did change! Here's the truth: when you use const, it's not that the value of that variable can't change. The object can change. Instead, using const means that you cannot reassign the aGreatObject variable to something else in memory. It must be assigned only once, to this object. But after that, the object is free to change.

var, let and const

Phew! Okay, in ES2015, var, let, and const do have some differences. But a lot of the time, you will see people use one or the other purely based on personal preference, or whatever is trendy that week. The differences are minor.

In our case, because you know I love to write hipster code, let's change each let to const. Start at the top: const $link makes sense. We don't need to reassign that. The same is true for deleteUrl, $row, $form, and formData:

'use strict';
(function(window, $, Routing, swal) {
... lines 4 - 26
$.extend(window.RepLogApp.prototype, {
... lines 28 - 47
handleRepLogDelete: function (e) {
... lines 49 - 50
const $link = $(e.currentTarget);
... lines 52 - 61
},
_deleteRepLog: function($link) {
... lines 65 - 70
const deleteUrl = $link.data('url');
const $row = $link.closest('tr');
... lines 73 - 82
},
... lines 84 - 88
handleNewFormSubmit: function(e) {
... lines 90 - 91
const $form = $(e.currentTarget);
const formData = {};
... lines 94 - 104
},
_saveRepLog: function(data) {
return new Promise((resolve, reject) => {
$.ajax({
... lines 110 - 112
}).then((data, textStatus, jqXHR) => {
... lines 114 - 119
}).catch((jqXHR) => {
const errorData = JSON.parse(jqXHR.responseText);
... lines 122 - 123
});
});
},
_mapErrorsToForm: function(errorData) {
... line 129
const $form = this.$wrapper.find(this._selectors.newRepForm);
$form.find(':input').each((index, element) => {
const fieldName = $(element).attr('name');
const $wrapper = $(element).closest('.form-group');
... lines 135 - 139
const $error = $('<span class="js-field-error help-block"></span>');
... lines 141 - 143
});
},
_removeFormErrors: function() {
const $form = this.$wrapper.find(this._selectors.newRepForm);
... lines 149 - 150
},
_clearForm: function() {
... lines 154 - 155
const $form = this.$wrapper.find(this._selectors.newRepForm);
... line 157
},
_addRow: function(repLog) {
const tplText = $('#js-rep-log-row-template').html();
const tpl = _.template(tplText);
const html = tpl(repLog);
... lines 165 - 167
}
});
/**
* A "private" object
*/
const Helper = function ($wrapper) {
this.$wrapper = $wrapper;
};
... lines 177 - 186
})(window, jQuery, Routing, swal);

Sure, we modify formData, but we know that's ok with const!

Keep going: $form, fieldName, $wrapper, $error... and eventually we get to the last one: totalWeight. But this variable can't be set to a const: we set it to 0, but then reassign it in each loop. This is a perfect case for let:

'use strict';
(function(window, $, Routing, swal) {
... lines 4 - 176
$.extend(Helper.prototype, {
calculateTotalWeight: function() {
let totalWeight = 0;
... lines 180 - 184
}
});
})(window, jQuery, Routing, swal);

Let's take our app for a spin! Refresh! And try deleting something. Woohoo! Yep, you can pretty much choose between var, let and cat, I mean, const.

Leave a comment!

0
Login or Register to join the conversation
Cat in space

"Houston: no signs of life"
Start the conversation!

This tutorial uses Symfony 3. But, since this is a JavaScript tutorial, all the concepts work fine in newer versions of Symfony.

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": "^7.2.0",
        "symfony/symfony": "3.2.*", // v3.2.14
        "twig/twig": "2.10.*", // v2.10.0
        "doctrine/orm": "^2.5", // v2.7.1
        "doctrine/doctrine-bundle": "^1.6", // 1.10.3
        "doctrine/doctrine-cache-bundle": "^1.2", // 1.3.2
        "symfony/swiftmailer-bundle": "^2.3", // v2.4.2
        "symfony/monolog-bundle": "^2.8", // v2.12.1
        "symfony/polyfill-apcu": "^1.0", // v1.3.0
        "sensio/distribution-bundle": "^5.0", // v5.0.22
        "sensio/framework-extra-bundle": "^3.0.2", // v3.0.19
        "incenteev/composer-parameter-handler": "^2.0", // v2.1.2
        "friendsofsymfony/user-bundle": "~2.0@dev", // dev-master
        "doctrine/doctrine-fixtures-bundle": "~2.3", // v2.4.1
        "doctrine/doctrine-migrations-bundle": "^1.2", // v1.2.1
        "composer/package-versions-deprecated": "^1.11", // 1.11.99
        "friendsofsymfony/jsrouting-bundle": "^1.6" // 1.6.0
    },
    "require-dev": {
        "sensio/generator-bundle": "^3.0", // v3.1.2
        "symfony/phpunit-bridge": "^3.0" // v3.2.2
    }
}
userVoice