let은 한번 선언하면 재선언이 안됨
var는 재선언이 가능함
let num = 10;
console.log(num); // 10
let num = 20; // Uncaught Error: already defined
console.log(num); // 10
var num = 10;
console.log(num); // 10
var num = 20;
console.log(num); // 20
그리고 var는 호이스팅이라고 해서 var가 쓰여진 위치와 관계없이 최상단에 오는 것처럼 취급되는 문제가 있음
console.log(num); // undefined
var num = 10;
console.log(num); // 10
console.log(num); // Uncaught Type Error
let num = 10;
console.log(num); // 10
근데 이게 뭐가 문제가 되냐면
다른 함수에서 let str = num.toString()을 한다고 쳐보자
의도대로면 "10"이라는 문자열이 str에 저장되어야 하겠지만
실제로는 "undefined"라는 문자열이 저장됨
둘다 유효한 문자열이기 때문에 직접 값을 찍어보기 전에 단순히 타입 체크만으론 잘 들어갔는지 잘못 들어갔는지 모른다는 것이다
말도 안되지 말도 안되는거 알고 무슨 상황인지 알고 var 구리다는거 다 아는데 그게 왜 "성능"이랑 상관이 있는지를 모르겠음 정말로 var를 쓰면 for 속도가 2배 느려지는 것도 아닌데
이런것도 성능이라면 성능인데 차라리 "기능적으로 하자가 있다"면 몰라 흔히들 성능이라고 표현하는 속도나 메모리 사용 뭐 이런 측면에서만 보면 차이가 없음
var은 블록스코프가 아닌 함수 스코프이다. 이걸 전역에서 사용했을때로 생각해보면 논리적으로 전역변술로 치환되는게 타당하긴함. 근데 자스 데이터 구조상 일반변수랑 전역변수 취급 자체가 완전히 다른데, 이걸 전역변수로 처리해버리는게 호이스팅의 문제이고 설계오류지. 그게 성능이랑 당연히 연결되는거고. 이걸 전혀 모르는 사람이 현상만 두고 봤을때 설계오류라고 생각할까? 이건 논외에요~ 라고 넘어가기엔 너무 큰 문제인데.
const max = 1000000
console.time('var')
for (var i = 0; i < max; i++) {}
console.timeEnd('var')
console.time('let')
for (let i = 0; i < max; i++) {}
console.timeEnd('let')
var: 3.643ms
let: 1.91ms
이건 충분히 큰 태스크 아닌거같은데
그리고 warm up 돌린거 맞음? 알다시피 어지간한 자스 런타임은 같은 코드 여러 번 돌리면 jit나 기타 최적화 들어가서 뒤에 실행되는 코드가 앞에 실행되는 코드보다 빨라지는건 알거고
내 환경에선 둘다 3.58 3.51로 차이없음 좀 더 규모 있고 유의미한 task로 테스트해봐야함
나도 let 등장 초창기 이야기에서 var 성능이 느린건 알고있었음.
그리고 2년전인가? 갤럼이 let이랑 var 성능차이 이해안간다는 글 봐서 테스트해봤고.
아마 그땐 브라우저 콘솔에서 대충 테스트해봐서 그런거같음
지금도 브라우저 콘솔에서 테스트하니까 jit안되네,, 콘솔 최적화는 생각을 못했다