A1. let은 let을 선언한 블록과 그 하위 블록을 스코프로 가진다. var는 var 선언을 포함한 함수까지 스코프로 가진다.
참고: MDN Web Docs let
function varTest() {
var x = 1;
if (true) {
var x = 2; // 같은 변수!
console.log(x); // 2
}
console.log(x); // 2
}
function letTest() {
let x = 1;
if (true) {
let x = 2; // 다른 변수
console.log(x); // 2
}
console.log(x); // 1
}
코드 출처: MDN Web Docs let
위 예제가 let과 var의 차이를 보여준다.
var로 변수를 선언할 경우 보통 의도하지 않은 결과가 나타난다. if문 안에 선언한 x가 if문 밖까지 영향을 주니까.
A2. 프로그램 최상위에서 사용할 경우 var는 전역 객체에 속성이 추가되고, let은 추가되지 않는다.
var x = 'global';
let y = 'global';
console.log(this.x); // "global"
console.log(this.y); // undefined
코드 출처: MDN Web Docs let
이런 var의 특성 때문에 이상하게 프로그램이 꼬일 가능성이 커진다. 서로 다른 js 파일을 html 파일 상에 불러 왔는데, 서로 다른 js 파일 최상위에 같은 변수명을 썼다면 꼬이게 된다.
예를 들어보자. 아래와 같은 html 파일을 만들자.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="a.js"></script>
<script src="b.js"></script>
</head>
<body>
<button onclick="test();">test</button>
</body>
</html>
a.js 파일
var x = "a.js";
console.log(x);
function test(){
console.log(x);
}
b.js 파일
var x = "b.js";
console.log(x);
위와 같이 하고, test 버튼을 클릭해서 test()를 실행하면 당연히 a.js가 출력될 것 같지만 b.js가 출력되고 만다.
a.js 안의 test() 함수를 실행했는데도 b.js가 출력된다.
js파일을 하나만 쓰지 않고 보통 여러 개를 쓰니, 어떤 문제가 생길지 알 수 없게 된다.
var만 let으로 변경해도 아래처럼 어쨌든 a.js라고 원하는 결과가 나타나고, 에러를 통해서 문제가 있다는 것을 인지할 수 있게 된다.
되도록 var보다 let을 쓰는 게 좋다.