선언 중복 시 에러가 나지 않는다면 새로 선언하려는 변수가 이미 있는 변수인지 확인하기가 어려워 의도하지 않은 대로 동작할 수 있다.
var < let/const
변수의 값이 변경될 가능성이 있는 경우 예상치 못한 에러가 생길 가능성이 높다.
var < let < const
코드 작성 순서와 런타임 때 작동하는 것은 다르다. 런타임에 예상못한 동작들이 발생된다.
var와 함수 선언식은 호이스팅과 동시에 할당된다.
호이스팅 시 할당될 때의 문제점
해결책
함수나 변수 선언 시 const, let을 써서 선언해야 실수를 줄일 수 있다.
블록 단위 스코프(let/const)여야 외부 변수의 오염을 막을 수 있다.
함수 레벨(var)의 경우 블록 안에서 변경을 해도 전역 변수에 영향을 미치게 된다.
예시1.
if조건이 맞을 때만 새로운 변수를 선언해서 출력해야하는데 같은 이름의 전역변수가 변경되어 버렸다.
var global = '전역';
If (global === '전역') {
var global = '지역';
console.log(global); // 지역
}
console.log(global); // 지역
예시2.
블록 밖과 안의 변수가 별개로 선언되게 됨.
블록 스코프가 사람이 생각한 대로 작동할 수 있게 됨.
let global = '전역';
If (global === '전역') {
let global = '지역';
console.log(global); // 지역
}
console.log(global); // 전역
변수의 값을 변경할 수 있는 가능성을 제거한다.
임시 변수, 객체, 배열이 생기는 순간 수정할 가능성이 생기는 것.
bad - 수정이 가능한 버전
function getElements() {
const result = {}; // 임시 객체
result.title = document.querySelector('.title');
result.text = document.querySelector('.text');
result.value = document.querySelector('.value');
return result;
}
good - 수정 불가능한 버전
변수를 조작할 여지를 아예 주지 않는다.
function getElements() {
return {
title: document.querySelector('.title');
text: document.querySelector('.text');
value: document.querySelector('.value');
}
}
함수 내부에서 let으로 선언한 변수에 접근해 수정할 가능성이 있다.
추가적인 스펙이 있을 경우 함수 자체를 수정하면 그 함수를 수정하는 많은 곳에서 문제가 생길 수 있다. 이미 만들어둔 함수를 변경 불가능하게 바로 리턴하는 방법으로 작성 한 후 추가 수정 사항은 리턴 값을 가지고 추가적인 조작을 해서 사용하는 게 좋다.
bad - 수정이 가능한 버전
function getDateTime(targetDate) {
let month = targetDate.getMonth();
let day = targetDate.getDate();
let hour = targetDate.Hours();
month = month >= 10 ? month : '0' + month;
day = day >= 10 ? day : '0' + day;
hour = hour >= 10 ? hour : '0' + hour;
return {
month,
day,
hour
}
}
good - 수정 불가능한 버전
function getDateTime(targetDate) {
const month = targetDate.getMonth();
const day = targetDate.getDate();
const hour = targetDate.Hours();
return {
month: month >= 10 ? month : '0' + month;
day: day >= 10 ? day : '0' + day;
hour: hour >= 10 ? hour : '0' + hour;
}
}
good - 기능 추가 버전
function getDateTime(targetDate) {
const currentDateTime = getDateTime(new Date());
return {
month: currentDateTime.month + '분 전';
day: currentDateTime.day + '분 전';
hour: currentDateTime.hour + '분 전';
}
}
function getSomeValue(number) {
let temp;
temp += number;
if(temp > 10) {
temp = 0;
}
}