Var is the ES5 standard for defining variables, while let is the ES6 standard. Backend programmers rarely notice the difference between the two, presumably knowing that both are keywords that define variables. Here’s an interesting code execution phenomenon to see the difference
demand
Bind click events for five buttons in the page, click any one of the buttons to pop up the click button value on the pageLet’s start with a simple implementation of this requirement, the implementation code is as follows:
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>the difference between var and let</title>
</head>
<script type="application/javascript">
// Bind a click function to each button and pop up the value of the button
window.onload = function () {
var btns = document.getElementsByTagName("button")
for (var i = 0; i <= btns.length - 1; i++) {
var btn = btns[i];
btn.addEventListener('click'.function () {
alert(btn.innerText)
})
}
}
</script>
<body>
<div id="box">
<button>button1</button>
<button>button2</button>
<button>button3</button>
<button>button4</button>
<button>button5</button>
</div>
</body>
</html>
Copy the code
The effect of the execution page is as follows:
Isn’t it strange to see that whatever button is clicked on pops up button5 instead of the value we expect, but if you put the topforThe loop code defines variablesiwithbtnThe keyword byvar
Instead oflet
The rerun will look like this:So if you look at these two operations, you might ask whyvarintoletThat’s how we want it to work, right? To explain this, we need to understand a concept:Block-level scope
Block-level scope
Take a look at the following code:
{
var x =123
}
// Console can print 123
console.log(x)
Copy the code
The above is{}
The code included is called a code block, which is certainly familiar to those with back-end development experience. The code console above can output the value of x as 123. But if we’re going tovarInstead ofletThe console will report the following error:
Thus, we know that the variables defined by let are only valid within the current code block, while ES5 has only function scope and global scope, without block-level scope, so {} cannot limit the access scope of var declared variables.
Because there is no block-level scope in ES5, it makes sense that the variable I defined by the for loop in the previous requirement code was exposed as a global variable, so whatever click was made becomes Button5. If the variable I is declared as let, the current I will only be valid for this loop, so each loop’s I is actually a new variable, so clicking on any button will bring up the value of the current button. We can also use closure functions in ES5 to solve this problem:
window.onload = function () {
var btns = document.getElementsByTagName("button")
for (var i = 0; i <= btns.length - 1; i++) {
(function () {
var btn = btns[i];
btn.addEventListener('click'.function () {
alert( btn.innerText)
})
})(i)
}
}
Copy the code
Although ES5 does not have block-level scopes, only functional scopes and global scopes are included. Variables defined by a function scope are valid only within the current function. So there is no problem of variable leakage.
The code address
Case code