First of all, don’t use var at all unless you need to support IE (and don’t have a transpiler such as babel in your build process) – the counterpart to const is let.
So which to use when? A good rule of thumb is to basically always use const. This guarantees that object references always point (and always have pointed) to the object to which they are supposed to point; and primitive values should rarely get changed either – they are constants as such. This makes bad practices like reusing variables impossible, and your code gets more predictable and easier to debug.
So use let only if you need to reassign a variable (for example, a counter variable in a for loop). Here are some examples:
// This value is never going to change during runtime
const PRODUCT_ENDPOINT = '/api/v2/products'
// You don't want to reassign an array -- elements can
// still get .push()ed and .pop()ped as usual
const myValues = [1, 42, 77]
// If you want to, say, .filter() that array, assign the
// result to a new variable instead:
const filteredValues = myValues.filter(n => n < 50)
// You can be confident that myElement always refers
// to the same element in the DOM
const myElement = document.getElementById('my-element')
// Even though this object has a mutable state, the
// counter itself should never be anything but
// that very counter
const counter = {
count: 0,
increment () {
this.count++
}
}
// Use let for loop variables
for (let i = 0; i < myValues.length; i++) {
console.log(myValues[i])
}
// Use let for flags
let windowLoaded = false
window.addEventListener('load', () => {
windowLoaded = true
})
// Use let if you explicitly need to dereference an object,
// usually to avoid memory leeks -- this is however a rather
// rare use case
let paymentWindow = window.open('/payment')
// When the window got closed, the reference is no longer needed
paymentWindow.addEventListener('unload', () => {
paymentWindow = null
})