변할 수 있는 수, 변할 수 있는 정보라는 뜻으로 파이썬에서의 변수와 같다. 차이점이라고 한다면 키워드를 앞에 붙여줘야 한다.
변수를 공부하기 전에 자바스크립트의 스코프에 대해 알아야 한다. 스코프는 범위라는 뜻인데 여기서는 코드가 변수에 접근할 수 있는 범위를 뜻한다.
스코프의 종류는 3가지가 있는데 var
키워드는 함수 스코프에 속하고 let
키워드는 블록 스코프, 최상위 함수 외부에 선언된 변수라면 글로벌 스코프를 갖게 된다.
위의 그림처럼 x라는 변수는 main 함수 스코프를 갖기에 함수 외부의 출력문은 x를 이용할 수 없다.
위 그림에서도 보다시피 x가 var
로 선언되어(함수 scope) if 블록 안의 x도 if 바깥의 x와 같은 스코프를 갖는다. 따라서 hi가 출력된다. var
는 변수의 중복 선언을 허용하기에 값이 덮어 씌워진 것이다.
이처럼 헷갈리는 var
대신 let
을 쓰는 이유가 이것말고도 여러가지 존재한다.
다른 이유로는 var
키워드를 사용하면 환경 변수에 있는 값이 덮어 씌워질 수도 있다. 또한, 같은 이름의 변수를 중복 사용할 수 있기에 팀프로젝트에서 다른 사람의 변수가 덮어 씌워질 수도 있다.
마지막 이유는 변수 호이스팅
이라는 이유가 있다. 변수 호이스팅
이란 프로그램이 실행되기 이전에 변수의 선언과 초기화를 분리하여 변수의 선언부분만 프로그램 맨위로 끌어 올려지는 것을 말한다. 즉, 자바스크립트 콘솔에게 사용할 변수(값은 제외)를 미리 알려주는 행위이다.
위의 코드는 사실 아래와 같이 실행된 것이다.
실행 결과를 보면 첫 번째 콘솔의 출력은 undefined
인데 이 var
키워드는 위로 끌어올려지면 자동으로 undefined
로 초기화를 해준다. 선언문 이전에 접근을 하는 이상한 짓을 한다는 얘기다. let
키워드는 이러한 상황에서 에러를 발생시킨다.
let
도 똑같이 호이스팅
하지만 변수의 초기화를 하지 않는다. 근데 왜 에러가 나는 것일까?
이것은 TDZ(일시적 사각지대)라는 것 때문인데 let
이 호이스팅
으로 끌어올려지긴 하지만 선언문이 실행될때까지 이 TDZ에 들어간다. 자바스크립트는 이 TDZ에 들어가있는 변수에 접근을 허용하지 않아 에러를 발생시킨다.
따라서 var
대신 let
을 사용하도록 하자.
if
라는 블록 안에 x가 정의되어 있는데 값이 제대로 나오는 이유가 무엇일까? var
키워드가 함수 스코프(함수 안에서만 작용) 이기 때문이다! 반면에 var
대신 let
키워드를 사용하면 에러가 난다.
let
키워드는 if
같은 블록 안에서만 작용하는 블록 스코프 이기 때문이다! 파이썬의 일반적인 변수선언과 같다고 생각하면 된다.
const
는 let
과 매우 유사한데 1가지 다른점은 변수가 아니라 상수이다. 따라서 한번 사용한 변수를 재할당 할 수 없다는 차이점이 있다.
그렇지만 상황에 따라서 재할당 되는 것 같은 경우가 있다. const
변수를 문자나 상수같은 원시타입
이 아니라 리스트 같은 객체타입
이면 내용물의 값은 변할 수 있기 때문이다.
var
let
const
valueA = 1; // var가 생략되었음
const my_name ="WADE";
if(true){ // -- 코드블록의 시작입니다. -- //
let valueB = 'Hello!';
const my_name ="WADE"; // 코드블록 밖의 my_name과 별개의 상수입니다.
} // -- 코드블록의 끝입니다. -- //
valueB = 'nice to meet you!'; // 변수 정의 이전에 값을 할당 할 수 없습니다!
let valueB = 'Hi!'; // 코드블록 안의 valueB와 별개의 변수입니다.
파이썬과 의미는 같다. 반복적으로 필요한 코드를 하나의 덩어리로 묶어서 필요할 때마다 꺼내 쓸 수 있도록 한 것을 함수라 한다.
기본 구조는 다음과 같다.
function 함수이름(parameter1, parameter2...) { // 함수의 선언
// 실행코드...
return 반환값
}
함수이름(argument1, argument2...) // 함수의 호출
파선아실 : 파라미터(매개변수)는 선언할때, 아규먼트(인자)는 실행할 때
콘솔 창에 표시되는 단순 출력이다.
function 안녕(파라미터){
console.log(파라미터);
console.log('hello');
return 100;
}
안녕() // undefined, hello, 100
함수 내부에서 return 구문을 만나면 함수는 즉시 종료되며 값을 반환한다.
function 안녕(){
console.log('hello')
console.log('hello')
console.log('hello')
return
console.log('hello')
console.log('hello')
console.log('hello')
}
안녕() // `hello` * 3
자바스크립트의 함수는 특이하게 아규먼트(인자)는 매개변수(파라미터)보다 적거나 많아도 에러가 발생하지 않는다.
존재하지 않는 값을 출력하면 undefined
가 출력된다. 함수에 return이 없어도 undefiend
// 함수 선언문
function sum(x, y){
return x + y;
}
// 함수 표현식
let sumXY = function(x, y){
return x + y;
};
console.log(sum(10, 20));
console.log(sumXY(10, 20));
여기서 구문은 자바스크립트 명령문으로, 어떤 작업을 수행하기 위한 코드 블록이다. if, switch, for문 등이 해당된다.
표현식은 값으로 평가될 수 있는 것이다. 숫자나 문자열 같은 값 자체나 5<3과 같은 비교 연산자 등이 해당된다.
function 함수1(x, y) {
return x + y
}
// 위 함수를 화살표 함수로 작성하면 아래와 같습니다.
let 함수1 = (x, y) => x + y
// 만악 함수 실행시 전달하는 인자가 한 개라면 소괄호를 생략할 수 있습니다.
let 함수2 = x => x + 10
// 화살표 함수 내부에서 한 줄 표현식만 반환한다면 return 키워드를 생략해도 됩니다.
let 함수3 = x => x + 10
let 결과 = 함수3(2);
console.log(결과); // 12
(function() {
console.log('이 함수는 만들어지자마자 바로 실행됩니다!');
})();
(function() {
document.querySelector(".btn").addEventListener("click", function(){
console.log('click!')
});
})();
이는 함수 내부 변수가 전역으로 저장되지 않기에 필요없는 전역 변수의 생성을 줄일 수 있다. 또한, 파이썬의 클로저와 비슷하게 내부 변수를 외부로부터 private하게 보호할 수 있다는 장점이 있다.