자바스크립트에서는 변수를 선언할 수 있는 방법이 3가지가 있다.
var와 let, 그리고 const가 있는데
let과 const는 es6문법에 추가된 변수 선언 방법이다.
그렇다면 기존에 var를 내버려두고 왜 추가되었는지 살펴보겠다.
var에 대한 문제점
1. hoisting
console.log(test);
test='테스트';
var test;
//console.log 결과값: undefined
var test를 맨 밑에 선언했는데 cosole.log(test) 결과는 undefined로 출력된다.
(※undefined란 변수가 선언됐지만 값이 할당되지 않았을 때 undefined가 할당된다).
또한,
console.log(test);
test='테스트';
console.log(test);
var test;
//console.log 결과값: undefined , '테스트'
위의 코드에서 test에 '테스트' 문자열을 할당한 후, console.log(test)를 출력하는 코드를 넣었다.
그리고 출력하니 결과는 undefined랑, '테스트'가 출력되었다.
이처럼 변수를 선언하지도 않았는데 왜 이런 값이 나타는 것인가??
그 이유는 바로 var hoisting 문제 때문이다.
(※hoisting이란 어느 위치에 선언했는지 상관없이 항상 맨 위로 선언을 끌어올려주는 것이다.)
var로 선언 변수가 hoisting되기 때문에 코드에서 맨 위로 위치되기 된다. 그래서 변수는 선언됐지만, 값이 할당이 안된 undefined가 출력된다.
그래서 맨 처음 코드 1번 라인에 console.log(test)를 출력해도 undefined가 출력된다.
2. block scope
var는 함수에 해당하는 block scope 만이 존재하고, 그 외에는 block scope가 없다.
무슨 말이냐면
function testVar(){
var value=7;
console.log(value); //result 7
}
testVar();
console.log(value); // result: value is not defined
함수 내부에 선언된 var는 함수 외부에서 참조할 수 없다. 모든 개발 언어에서 이와 동일하기 때문에 당연하다 생각이 든다.
하지만,
function testVar(){
var value=7;
console.log(value); //7
if(true){
var valueTwo=10;
}
console.log(valueTwo); //10
}
testVar();
if 내부에서 선언한 변수를 외부에서 참조할 수 있다.
다른 개발언어는 변수가 if와 for문의 블록 스코프가 있기 때문에 이런 일이 발생하지 않는다.
즉, 함수 블록 스코프 이외에는 다른 블록 스코프를 갖고 있지 않다.
이로 인해, 프로그래밍 도중 문제가 발생할 수 있다.
var의 문제점을 해결할 수 있는 새로운 변수 선언방법 'let'
let을 사용하면 var의 hoisting문제와 block scope문제를 모두 해결할 수 있다.
1. hoisting 해결
위의 코드에서
console.log(test);
test='테스트';
let test;
//console.log 결과값: Cannot access 'test' before initialization
var 형식으로 let을 선언하면 선언전에 test 변수에 접근할 수 없다고 에러가 뜬다.
그래서 먼저 let은 변수를 선언 후 진행해야한다.
let test;
test='테스트';
console.log(test);
//console.log 결과값: '테스트'
2. block scope 해결
function testVar(){
var value=7;
console.log(value); //7
if(true){
let valueTwo=10;
}
console.log(valueTwo); //valueTwo is not defined
}
testVar();
위의 코드의 valueTwo의 변수를 var에서 let방법으로 바꿨다.
let은 함수 스코프뿐만 아니라 if, for, 개인 block scope를 갖고 있기 때문에 외부에서 참조할 수 없다.
그래서 위의 코드에서 if문 내부에 선언한 valueTwo 변수는 if문 외부에서 참조할 수 없다.
let의 특징
let은 변수를 선언과 할당을 같이 하던가, 선언 후에 할당을 따로 해도된다.
let val1;
val1=3;
let val2=4;
val2=6;
코드와 같이 가능하다.
또한, 기존의 val2의 값을 6으로도 변경시킬 수 있다.
그 이유는 let으로 선언한 변수는 메모리에서 값을 읽고 쓰기가 가능하기 때문이다.
const 변수
const 변수는 다른 개발언어와 마찬가지로 '상수'이다.
(※상수: 변하지 않는 수)
그래서 const라고 선언한 변수는 값을 바꾸지 못한다.
const test=5;
test=4;
console.log(test);//result: Assignment to constant variable
값을 변경하면 오류가 뜨는 것을 볼 수 있다.
오류가 뜨는 이유는 const로 생성한 변수는 메모리에서 읽기만 가능하기 때문이다.
const로 선언한 변수를 선언과 할당을 동시에 한 다음에는 변경할 수 없게 잠긴다고 생각하면된다. 그래서 읽기만 가능하다.
또한, 선언과 동시에 값을 할당해야 한다.
const test;
test =3;
console.log(test); //result: Missing initializer in const declaration
이렇게 선언과 할당을 따로 하면 에러가 생기므로,
const test=3; 이런 식으로 선언과 할당을 한 번에 해야 한다.
그렇다면 const를 왜 사용할까
1. 보안상의 이유: 만약, let으로 작성했다면 헤커들이 변수의 값을 임의로 바꿔 값을 계속 변경해나가며 프로그램에 영향을 줄 수 있다. 하지만 const로 바꾸면 값을 변경하지 못한다.
2. thread safey: 프로그램이 실행되면 하나의 프로세스가 할당되는데, 이때 프로세스 내에 다양한 스레드가 동시에 돌아가며 프로그램을 더욱 효율적이고 빠르게 동작시켜준다. 그런데 스레드들이 동시에 한 변수에 접근했을 때, 값을 여러 값으로 변경하게 되면 위험하다. 그래서 const로 지정해놓으면 그런 일을 사전에 방지할 수 있다.
3. 개발자의 실수: 개발하다 보면 자신도 모르게 그 값을 변경할 수 있다. 그래서 값이 변하지 않아야 할 값이라면 const로 변수를 설정해서 실수를 방지하기 위해 사용한다.
참고: www.youtube.com/watch?v=OCCpGh4ujb8&list=PLv2d7VI9OotTVOL4QmPfvJWPJvkmv6h-2&index=3
'Javascript' 카테고리의 다른 글
화살표 함수 this(arrow function this) (0) | 2020.11.11 |
---|---|
비교 연산자 (0) | 2020.10.16 |
hoisting(호이스팅) (0) | 2020.10.16 |
자바스크립트 객체 (0) | 2020.08.21 |
데이터 타입 (0) | 2020.08.19 |