Hoisting (호이스팅)
JavaScript에서 변수와 함수 선언은 해당 스코프의 최상단으로 끌어올려지는 현상이 있다.
이를 호이스팅(Hoisting)이라고 한다. 함수와 변수의 선언 방식에 따라 동작이 다르다.
함수 선언문 (Function Declaration)
- 호이스팅 발생 : 함수가 코드 실행 전에 메모리에 등록되므로 선언 전에 호출 가능.
hoisting() // 함수 호이스팅 = function is hoisted
function hoisting() {
console.log('function is hoisted')
}
함수 표현식 (Function Expression)
- 변수 호이스팅 발생 : 변수만 선언되고 초기화는 되지 않으므로 선언 전에 호출하면 오류 발생.
hoisting() // 변수 호이스팅 = ReferenceError: Cannot access 'hoisting' before initialization
let hoisting = function () {
console.log('variable is hoisted')
}
함수와 메소드의 차이
- 함수(Function) : 독립적으로 정의된 코드 블록으로 특정 작업을 수행하거나 값을 반환한다.
- 메소드(Method) : 클래스나 객체 내부에 정의된 함수로 해당 객체의 속성에 접근하거나 객체와 관련된 작업을 수행한다.
주요 차이점
- 독립성 : 함수는 독립적이지만, 메소드는 특정 객체에 속한다.
- this사용 여부 : 메소드는 this 키워드를 사용해 객체의 속성에 접근할 수 있다.
클래스와 캡슐화
클래스는 캡슐화(encapsulation)를 통해 내부 필드를 숨기고 외부에는 최소한의 메소드만 공개한다.
클래스 내부에서 this는 해당 클래스의 필드를 가리킨다.
class Example {
constructor(name) {
this.name = name;
}
getName() {
return this.name;
}
}
화살표 함수
화살표 함수는 표현이 간결할 뿐만 아니라 this가 존재하지 않는다.
따라서 상위 스코프의 this를 그대로 사용한다.
특징
- this, arguments, new.target이 없음
- 동적 바인딩이 아닌 정적 바인딩(Lexical Scope)
- 메소드로 사용 불가
const arrowFunc = () => {
console.log("화살표 함수");
};
주의사항
- 화살표 함수는 메소드로 사용할 수 없다. 클래스 내부에서 this에 접근하려면 일반 함수를 사용해야 한다.
class Example {
name = "example";
logName = () => {
console.log(this.name); // 상위 스코프의 this
};
}
변수 스코프와 바인딩
- var : 함수 스코프. 글로벌 환경에 바인딩됨
- let, const : 블록 스코프. 해당 블록 내에서만 접근 가능
일반 함수와 화살표 함수의 this
- 일반 함수
- 호출 컨텍스트에 따라 this가 달라짐
- this는 메소드로 호출되면 객체를, 함수로 호출되면 전역 객체를 참조
- 화살표 함수
- this가 없으므로 상위 스코프의 this를 사용
const obj = {
name: "example",
regularFunc: function() {
console.log(this.name); // example
},
arrowFunc: () => {
console.log(this.name); // undefined (상위 스코프 참조)
}
};
암시적 바인딩과 명시적 바인딩
- 암시적 바인딩 : 객체 내부 메소드에서 this를 통해 객체 필드에 접근
- 명시적 바인딩 : call, apply, bind를 사용해 this를 특정 객체로 설정
const obj = { name: "example" };
function logName() {
console.log(this.name);
}
logName.call(obj); // 명시적 바인딩: example
객체 생성 방법
- 함수와 new 키워드 사용
- 클래스를 사용
- JSON 리터럴로 생성
function User(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
const user3 = new User("Name", "Test");
console.log(user3.firstName); // Name
console.log(user3.lastName); // Test
// 클래스 예시
class User {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
// JSON 예시
{
name: "TestName",
age : 10,
}
접근 제어자
JavaScript에서 클래스의 필드와 메소드는 기본적으로 공개(public)이다.
접근 제어자를 사용하면 정보 은닉이 가능하다.
- Private 필드 : #을 필드명 앞에 추가
- Private 메소드 : #을 메소드명 앞에 추가
class User {
#firstName;
#lastName;
constructor(firstName, lastName) {
this.#firstName = firstName;
this.#lastName = lastName;
}
#getFullName() {
return `${this.#firstName} ${this.#lastName}`;
}
printName() {
console.log(this.#getFullName());
}
}
ESM vs CJS
- ESM (ECMAScript Module)
- 필요할 때만 임포트 가능
- 비동기 가능 (백엔드에서 사용)
- CJS (CommonJS)
- 모든 모듈을 한 번에 임포트
- 비동기 불가 (프론트엔드에서 사용)
// ESM
import { moduleName } from "module";
// CJS
const moduleName = require("module");
Callback과 Promise
Callback
- Callback : 함수의 파라미터로 전달되어 실행권을 이양받는 함수
- 주로 비동기 함수에서 사용됨
function asyncFunc(callback) {
setTimeout(() => {
callback("비동기 완료");
}, 1000);
}
asyncFunc(result => console.log(result));
특징
- 콜백 지옥(Callback Hell)으로 코드 가독성이 떨어질 수 있음
- 에러 처리가 복잡해질 수 있음
Promise
- Promise는 Callback과 비동기 로직을 결합한 객체
- 비동기 작업의 상태를 표현하며 3가지 상태로 나뉜다.
- Pending : 수행 중
- Fulfilled : 성공 (이행) = 연산이 성공적으로 완료된 상태
- Rejected : 실패 (거부) = 연산이 실패한 상태
const promise = new Promise((resolve, reject) => {
const success = true;
if (success) resolve("성공");
else reject("실패");
});
promise
.then(result => console.log(result))
.catch(error => console.error(error));
장점
- 콜백 지옥을 해결하여 가독성이 향상
- 체이닝을 통해 비동기 작업을 순차적으로 처리 가능
Async/Await
- async 키워드는 함수를 Promise로 변환
- await는 Promise가 해결될 때까지 기다림
- 기존의 .then() 체이닝 방식보다 가독성이 높음
async function fetchData() {
try {
const result = await promise;
console.log(result);
} catch (error) {
console.error(error);
}
}
fetchData();
특징
- 동기적인 코드 흐름처럼 보이지만 실제로는 비동기 작업을 처리
- try-catch 블록으로 에러를 처리할 수 있음
- 비동기 함수 내부의 return 값은 자동으로 Promise로 래핑됨
'공부' 카테고리의 다른 글
[ASAC] JavaScript 심층 탐구 : 함수, 객체, 그리고 엔진 동작 방식 (1) | 2025.01.01 |
---|---|
[ASAC] Git CLI 학습 (1) | 2024.12.29 |
[ASAC] 리눅스 쉘(Shell) 명령어 정리 (0) | 2024.12.29 |
[ASAC] 코드 관리 : Git & GitHub (2) | 2024.12.28 |
[ASAC] 웹 보안 기초 : CORS와 CSRF의 이해 (1) | 2024.12.27 |