Javascript 변수 선언방법
1. var
- ES5 이전부터 사용된 변수 선언 방식이다.
- 함수 스코프(Function Scope)를 가진다.
- 동일한 변수명을 중복 선언 가능하다.
- 재선언, 재할당 모두 가능하다.
var a = 10;
var a = 20;
a 를 이미 선언했음에도 a를 두번 선언 할수 있다.
이때 a의 값은 20
- 호이스팅(hoisting)이 발생하며, 선언은 끌어올려지지만 값은 undefined로 초기화된다.
다음 코드로 예를 들자면.
console.log(a);
var a = 10;
사람이 보기에는 a 가 아직 선언되지 않은 것처럼 보인다.
그러나 JavaScript 엔진은 내부적으로 다음과 같이 처리한다.
var a; // 선언이 먼저 처리됨 (초기값: undefined)
console.log(a);
a = 10; // 할당은 원래 위치에서 실행됨
따라서 출력 결과는 다음과 같다.
undefined
2. let
- ES6(2015)부터 도입된 변수 선언 방식이다.
- 블록 스코프(Block Scope)를 가진다.
- 중복 선언 불가하다.
- 재할당 가능하다.
- 호이스팅은 발생하지만, TDZ(Temporal Dead Zone)로 인해 선언 이전 접근 시 에러가 발생한다.
TDZ의 의미
변수가 선언되었지만, 아직 사용할 수 없는 금지 구간을 의미한다.
3. const
- ES6에서 도입된 상수 선언 방식이다.
- 블록 스코프(Block Scope)를 가진다.
- 중복 선언 불가하다.
- 재할당 불가하다.
const z = 10;
// z = 20; // 오류
객체나 배열의 경우 참조 자체는 변경 불가하지만, 내부 값은 변경 가능하다. (변수의 주소값이 재할당 불가)
const obj = { a: 1 };
obj.a = 2; // 가능
obj = { b: 1 }; // 불가
- 선언과 동시에 반드시 초기화해야 한다.
스코프란?
스코프는 변수에 접근할 수 있는 범위를 말한다.
- 어디에서 선언되었는지
- 어디까지 사용할 수 있는지
를 결정하는 규칙이다.
함수 스코프
1. 함수 안에서 선언되면 -> 그 함수 전체에서 사용 가능
function test() {
var x = 10;
console.log(x); // 10
}
test();
console.log(x); // ❌ ReferenceError
function test() {
if (true) {
var y = 20;
}
console.log(y); // 20
}
2. 함수 밖에서 선언되면 -> 전역 변수
if (true) {
var z = 30;
}
console.log(z); // 30
이며, if, for, while 같은 블록은 스코프를 만들지 않는다.
블록 스코프
1. 선언된 블록 안에서만 접근 가능
2. 블록을 벗어나면 존재하지 않는 변수
if (true) {
let a = 10;
const b = 20;
console.log(a, b); // 10 20
}
console.log(a); // ❌ ReferenceError
console.log(b); // ❌ ReferenceError
메서드와 함수의 차이
1) 함수(Function)
함수는 독립적으로 정의되고 호출되는 코드 블록이다.
function add(a, b) {
return a + b;
}
add(1, 2);
- 특정 객체에 속하지 않음.
- 전역 함수 또는 변수에 할당된 함수 형태.
- 호출 시this는 상황에 따라 undefined 또는 전역 객체를 참조함. (strict mode에서는 undefined)
2) 메서드(method)
메서드는 객체의 프로퍼티로 존재하는 함수이다.
const calculator = {
add(a, b) {
return a + b;
}
};
calculator.add(1, 2);
- 객체에 소속된 함수
- 호출 주체가 객체임
- 호출 시 this는 해당 객체를 가리킴
calculator.add = function () {
console.log(this);
};
calculator.add(); // calculator 객체
자바스크립트의 함수의 종류
1) 함수 선언문 (Function Declaration)
가장 기본적인 형태이다.
function add(a, b) {
return a + b;
}
- 호이스팅됨 (선언 전에 호출 가능)
- 전역 또는 블록 스코프에서 사용 가능
- 가장 안정적인 함수 정의 방식
2)함수 표현식 (Function Expression)
함수를 변수에 할당하는 방식이다.
const add = function (a, b) {
return a + b;
};
- 변수만 호이스팅됨 (함수는 아님)
- 선언 이전 호출 불가
- 클로저, 콜백에 자주 사용됨
3) 화살표 함수 (Arrow Function)
ES6에서 도입된 간결한 함수 표현 방식이다.
const add = (a, b) => a + b;
- this, arguments를 바인딩하지 않음
- 상위 스코프의 this를 그대로 사용
- 생성자(new)로 사용 불가
- 메서드보다는 콜백에 적합
4) 즉시 실행 함수 (IIFE)
정의하자마자 실행되는 함수이다.
(function () {
console.log("즉시 실행");
})();
- 한 번만 실행됨
- 스코프 분리 목적
- 과거 모듈 패턴에서 많이 사용됨
5) 콜백 함수 (Callback Function)
- 다른 함수의 인자로 전달되는 함수이다.
setTimeout(function () {
console.log("콜백");
}, 1000);
- 비동기 처리에 필수
- 고차 함수와 함께 사용됨
- 화살표 함수 사용 빈도 높음
6) 고차 함수 (Higher-Order Function)
함수를 인자로 받거나 반환하는 함수이다.
function multiplier(factor) {
return function (x) {
return x * factor;
};
}
- 함수형 프로그래밍 핵심 개념
- map, filter, reduce가 대표적 예시
7) 생성자 함수 (Constructor Function)
객체 생성을 목적으로 사용하는 함수이다.
function User(name) {
this.name = name;
}
const user = new User("Kim");
- new 키워드와 함께 사용
- 관례적으로 함수명은 대문자로 시작
- 클래스 문법의 이전 형태
8) 메서드 (Method)
객체에 속한 함수이다.
const user = {
sayHello() {
console.log("Hello");
}
};
- 객체의 행위를 표현
- 호출 시 this는 객체 자신
9) 재귀 함수 (Recursive Function)
자기 자신을 호출하는 함수이다.
function factorial(n) {
if (n === 1) return 1;
return n * factorial(n - 1);
}
- 종료 조건 필수
- 트리, 분할 정복 알고리즘에 사용됨
10) 제너레이터 함수 (Generator Function)
중간 실행을 멈췄다 다시 실행할 수 있는 함수이다.
function* generator() {
yield 1;
yield 2;
}
- yield 키워드 사용
- 반복자(iterator)를 반환
- 비동기 흐름 제어에 활용 가능
11) 비동기 함수 (Async Function)
비동기 처리를 동기 코드처럼 작성하는 함수이다.
async function fetchData() {
const data = await fetch("/api");
return data;
}
- 항상 Promise 반환
- await 사용 가능
- 에러 처리는 try-catch 사용