JavaScript 기초
JavaScript 기초
JavaScript는 웹 페이지에 상호작용성을 부여하는 프로그래밍 언어로, 현대 웹 개발의 핵심 요소입니다. 원래는 브라우저에서만 실행되었지만, 현재는 Node.js와 같은 환경을 통해 서버 측에서도 실행될 수 있습니다.
JavaScript 개요
JavaScript의 역할
웹 개발에서 JavaScript는 다음과 같은 역할을 합니다:
- HTML과 CSS로 만든 정적 웹 페이지에 동적 기능 추가
- 사용자 입력에 반응하는 대화형 요소 생성
- 서버와의 비동기 통신을 통한 데이터 교환
- 복잡한 웹 애플리케이션 및 싱글 페이지 애플리케이션(SPA) 개발
- 서버 사이드 애플리케이션 개발 (Node.js 사용)
JavaScript 작성 및 실행 방법
JavaScript 코드를 HTML 페이지에 포함시키는 세 가지 방법이 있습니다:
1. 인라인 스크립트: HTML 요소의 이벤트 속성 내에 직접 작성 ```html <button onclick="alert('안녕하세요!')">클릭하세요</button> ```
2. 내부 스크립트: HTML 문서 내 <script> 태그 안에 작성 ```html <script>
function greet() { alert('안녕하세요!'); }
</script> ```
3. 외부 스크립트: 별도의 .js 파일에 작성하고 HTML에 링크 (권장) ```html <script src="script.js"></script> ```
변수와 데이터 타입
변수 선언
JavaScript에서 변수를 선언하는 세 가지 방법이 있습니다:
```javascript // var: 함수 스코프, 재선언 및 재할당 가능 (레거시) var name = "홍길동";
// let: 블록 스코프, 재할당 가능 let age = 25;
// const: 블록 스코프, 재할당 불가능 (권장) const PI = 3.14; ```
기본 데이터 타입
JavaScript의 기본 데이터 타입은 다음과 같습니다:
데이터 타입 | 설명 | 예시 |
---|---|---|
String | 텍스트 데이터 | "Hello", 'World', `Template` |
Number | 모든 숫자 (정수, 소수) | 42, 3.14, -7 |
Boolean | 논리적 참/거짓 값 | true, false |
Undefined | 값이 할당되지 않은 변수 | undefined |
Null | 의도적으로 비어있음을 나타내는 값 | null |
Symbol | 고유하고 변경 불가능한 값 | Symbol('id') |
BigInt | 매우 큰 정수를 저장할 수 있는 타입 | 1234567890123456789n |
참조 데이터 타입
복합 데이터 타입으로 다음과 같습니다:
데이터 타입 | 설명 | 예시 |
---|---|---|
Object | 키-값 쌍의 컬렉션 | {name: "홍길동", age: 25} |
Array | 순서가 있는 값의 컬렉션 | [1, 2, 3, 4, 5] |
Function | 실행 가능한 코드 블록 | function() { return "Hello"; } |
Date | 날짜와 시간을 나타내는 객체 | new Date() |
RegExp | 정규 표현식을 나타내는 객체 | /pattern/ |
타입 확인과 변환
```javascript // typeof 연산자로 타입 확인 typeof "문자열"; // "string" typeof 42; // "number" typeof true; // "boolean" typeof {}; // "object"
// 타입 변환 let num = 42; let str = String(num); // 숫자 → 문자열: "42" let bool = Boolean(num); // 숫자 → 불리언: true let numFromStr = Number("42"); // 문자열 → 숫자: 42 ```
연산자
산술 연산자
```javascript let a = 10; let b = 3;
let sum = a + b; // 13 (덧셈) let difference = a - b; // 7 (뺄셈) let product = a * b; // 30 (곱셈) let quotient = a / b; // 3.333... (나눗셈) let remainder = a % b; // 1 (나머지) let power = a ** b; // 1000 (거듭제곱)
// 증감 연산자 let c = 5; c++; // 후위 증가: c = 6 ++c; // 전위 증가: c = 7 c--; // 후위 감소: c = 6 --c; // 전위 감소: c = 5 ```
비교 연산자
```javascript let x = 5; let y = "5";
// 동등 비교와 일치 비교 x == y; // true (값만 비교) x === y; // false (값과 타입 모두 비교, 권장) x != y; // false (값만 비교) x !== y; // true (값과 타입 모두 비교, 권장)
// 크기 비교 x > 3; // true x >= 5; // true x < 10; // true x <= 4; // false ```
논리 연산자
```javascript let p = true; let q = false;
// AND, OR, NOT p && q; // false (AND: 둘 다 true여야 true) p || q; // true (OR: 하나라도 true면 true) !p; // false (NOT: 부정)
// 단축 평가 let a = null; let b = "Hello"; let result = a || b; // "Hello" (첫 번째 truthy 값 반환) let display = a && b; // null (첫 번째 falsy 값 반환) ```
기타 연산자
```javascript // 삼항 연산자 let age = 20; let status = (age >= 18) ? "성인" : "미성년자"; // "성인"
// 할당 연산자 let x = 10; x += 5; // x = x + 5;와 동일 (15) x -= 3; // x = x - 3;와 동일 (12) x *= 2; // x = x * 2;와 동일 (24) x /= 4; // x = x / 4;와 동일 (6)
// 전개 연산자 (Spread Operator) let arr1 = [1, 2, 3]; let arr2 = [...arr1, 4, 5]; // [1, 2, 3, 4, 5]
// 비구조화 할당 (Destructuring) let [a, b] = [1, 2]; // a=1, b=2 let {name, age} = {name: "홍길동", age: 25}; // name="홍길동", age=25 ```
조건문과 반복문
if 문
```javascript let score = 85;
if (score >= 90) {
console.log("A 등급");
} else if (score >= 80) {
console.log("B 등급"); // 실행됨
} else if (score >= 70) {
console.log("C 등급");
} else {
console.log("F 등급");
} ```
switch 문
```javascript let day = new Date().getDay(); // 0(일) ~ 6(토)
switch (day) {
case 0: console.log("일요일"); break; case 1: console.log("월요일"); break; // 다른 요일들... default: console.log("유효하지 않은 요일");
} ```
for 반복문
```javascript // 기본 for 루프 for (let i = 0; i < 5; i++) {
console.log(i); // 0, 1, 2, 3, 4
}
// for...of (배열의 값 반복) let fruits = ["사과", "바나나", "오렌지"]; for (let fruit of fruits) {
console.log(fruit); // "사과", "바나나", "오렌지"
}
// for...in (객체의 키 반복) let person = {name: "홍길동", age: 25, job: "개발자"}; for (let key in person) {
console.log(key + ": " + person[key]);
} ```
while과 do...while 반복문
```javascript // while 루프 let i = 0; while (i < 5) {
console.log(i); // 0, 1, 2, 3, 4 i++;
}
// do...while 루프 (최소 한 번은 실행) let j = 0; do {
console.log(j); // 0, 1, 2, 3, 4 j++;
} while (j < 5); ```
함수
함수 선언과 표현식
```javascript // 함수 선언 (호이스팅됨) function greet(name) {
return "안녕하세요, " + name + "님!";
}
// 함수 표현식 (호이스팅되지 않음) const sayHello = function(name) {
return "안녕하세요, " + name + "님!";
};
// 화살표 함수 (ES6) const welcome = (name) => {
return "환영합니다, " + name + "님!";
};
// 화살표 함수 간략화 (단일 표현식) const add = (a, b) => a + b; ```
매개변수와 반환 값
```javascript // 기본 매개변수 function greet(name = "손님") {
return "안녕하세요, " + name + "님!";
} greet(); // "안녕하세요, 손님님!" greet("홍길동"); // "안녕하세요, 홍길동님!"
// 나머지 매개변수 function sum(...numbers) {
return numbers.reduce((total, num) => total + num, 0);
} sum(1, 2, 3, 4, 5); // 15
// 여러 값 반환 (배열/객체 사용) function getPersonInfo() {
return { name: "홍길동", age: 25, job: "개발자" };
} const { name, age } = getPersonInfo(); ```
스코프와 클로저
```javascript // 전역 및 지역 스코프 let globalVar = "전역 변수";
function testScope() {
let localVar = "지역 변수"; console.log(globalVar); // "전역 변수" (접근 가능) console.log(localVar); // "지역 변수"
}
console.log(globalVar); // "전역 변수" console.log(localVar); // 오류: localVar is not defined
// 클로저 function createCounter() {
let count = 0; // 내부 변수 return function() { return ++count; // 내부 변수에 접근하고 수정 };
}
const counter = createCounter(); console.log(counter()); // 1 console.log(counter()); // 2 console.log(counter()); // 3 ```
객체와 배열
객체 생성과 조작
```javascript // 객체 리터럴 let person = {
name: "홍길동", age: 25, job: "개발자", greet: function() { return "안녕하세요, " + this.name + "입니다."; }
};
// 속성 접근 console.log(person.name); // "홍길동" console.log(person["age"]); // 25 console.log(person.greet()); // "안녕하세요, 홍길동입니다."
// 객체 속성 추가, 수정, 삭제 person.email = "hong@example.com"; // 속성 추가 person.age = 26; // 속성 수정 delete person.job; // 속성 삭제
// 객체 메서드 let keys = Object.keys(person); // ["name", "age", "email", "greet"] let values = Object.values(person); // ["홍길동", 26, "hong@example.com", function] let entries = Object.entries(person); // [["name", "홍길동"], ["age", 26], ...] ```
배열 생성과 조작
```javascript // 배열 생성 let numbers = [1, 2, 3, 4, 5]; let fruits = ["사과", "바나나", "오렌지"]; let mixed = [1, "text", true, null, {key: "value"}];
// 배열 요소 접근 console.log(fruits[0]); // "사과" console.log(fruits[2]); // "오렌지"
// 배열 메서드 fruits.push("포도"); // 끝에 추가: ["사과", "바나나", "오렌지", "포도"] let lastFruit = fruits.pop(); // 끝에서 제거: "포도", fruits = ["사과", "바나나", "오렌지"] fruits.unshift("키위"); // 앞에 추가: ["키위", "사과", "바나나", "오렌지"] let firstFruit = fruits.shift(); // 앞에서 제거: "키위", fruits = ["사과", "바나나", "오렌지"]
// 배열 메서드 - 변환과 검색 let numbers = [1, 2, 3, 4, 5];
// map: 모든 요소를 변환 let doubled = numbers.map(num => num * 2); // [2, 4, 6, 8, 10]
// filter: 조건에 맞는 요소만 필터링 let evens = numbers.filter(num => num % 2 === 0); // [2, 4]
// reduce: 값을 누적 let sum = numbers.reduce((total, num) => total + num, 0); // 15
// find: 조건에 맞는 첫 번째 요소 찾기 let found = numbers.find(num => num > 3); // 4
// some: 하나라도 조건을 만족하는지 확인 let hasEven = numbers.some(num => num % 2 === 0); // true
// every: 모든 요소가 조건을 만족하는지 확인 let allPositive = numbers.every(num => num > 0); // true ```
DOM 조작
DOM(Document Object Model)은 JavaScript를 사용하여 HTML 문서를 조작할 수 있게 해주는 프로그래밍 인터페이스입니다.
요소 선택
```javascript // ID로 요소 선택 const header = document.getElementById("header");
// CSS 선택자로 첫 번째 요소 선택 const container = document.querySelector(".container");
// CSS 선택자로 모든 요소 선택 const paragraphs = document.querySelectorAll("p");
// 클래스명으로 요소 선택 const menuItems = document.getElementsByClassName("menu-item");
// 태그명으로 요소 선택 const buttons = document.getElementsByTagName("button"); ```
요소 조작
```javascript // 콘텐츠 변경 element.textContent = "새로운 텍스트"; // 텍스트만 변경 element.innerHTML = "강조된 텍스트"; // HTML 포함 변경
// 속성 조작 element.setAttribute("id", "new-id"); // 속성 설정 const value = element.getAttribute("href"); // 속성 값 가져오기 element.removeAttribute("disabled"); // 속성 제거
// 스타일 조작 element.style.color = "blue"; element.style.backgroundColor = "yellow"; element.style.fontSize = "16px";
// 클래스 조작 element.classList.add("active"); element.classList.remove("hidden"); element.classList.toggle("expanded"); element.classList.contains("active"); // 클래스 존재 확인 ```
요소 생성 및 삭제
```javascript // 새 요소 생성 const newParagraph = document.createElement("p"); newParagraph.textContent = "이것은 새로운 단락입니다.";
// DOM에 요소 추가 parentElement.appendChild(newParagraph); // 자식 요소로 추가 parentElement.insertBefore(newParagraph, referenceElement); // 특정 요소 앞에 추가
// 요소 복제 const clone = element.cloneNode(true); // true: 자식 요소 포함 복제
// 요소 삭제 element.remove(); // 요소 자체 삭제 parentElement.removeChild(childElement); // 부모 요소에서 자식 요소 삭제 ```
이벤트 처리
```javascript // 이벤트 리스너 추가 const button = document.querySelector("button");
// 방법 1: addEventListener button.addEventListener("click", function(event) {
console.log("버튼이 클릭되었습니다!"); console.log(event); // 이벤트 객체
});
// 방법 2: 이벤트 속성 button.onclick = function() {
console.log("버튼이 클릭되었습니다!");
};
// 이벤트 전파 제어 element.addEventListener("click", function(event) {
event.stopPropagation(); // 이벤트 버블링 중지 event.preventDefault(); // 기본 동작 방지 (예: 링크 클릭)
});
// 일반적인 이벤트 유형 // click, dblclick, mouseover, mouseout, keydown, keyup, submit, load, resize, scroll ```
비동기 JavaScript
콜백 함수
```javascript // 기본 콜백 패턴 function fetchData(callback) {
setTimeout(() => { const data = { name: "홍길동", age: 25 }; callback(data); }, 1000);
}
fetchData(function(data) {
console.log("데이터 수신:", data);
});
// 콜백 지옥 예시 fetchUserData(function(user) {
fetchUserPosts(user.id, function(posts) { fetchPostComments(posts[0].id, function(comments) { // 콜백 중첩이 깊어질수록 코드 가독성이 떨어짐 console.log(comments); }); });
}); ```
Promise
```javascript // Promise 생성 const fetchData = new Promise((resolve, reject) => {
setTimeout(() => { const success = true; if (success) { resolve({ name: "홍길동", age: 25 }); } else { reject("데이터를 가져오는 데 실패했습니다."); } }, 1000);
});
// Promise 사용 fetchData
.then(data => { console.log("데이터 수신:", data); return processData(data); // 다른 Promise 반환 가능 }) .then(processedData => { console.log("처리된 데이터:", processedData); }) .catch(error => { console.error("오류 발생:", error); }) .finally(() => { console.log("작업 완료"); });
// Promise 체이닝 (콜백 지옥 개선) fetchUserData(userId)
.then(user => fetchUserPosts(user.id)) .then(posts => fetchPostComments(posts[0].id)) .then(comments => console.log(comments)) .catch(error => console.error(error));
```
async/await
```javascript // async/await 사용법 async function fetchUserDataAndPosts() {
try { // await는 Promise가 해결될 때까지 실행을 일시 중지 const user = await fetchUserData(userId); const posts = await fetchUserPosts(user.id); const comments = await fetchPostComments(posts[0].id); console.log(comments); return comments; } catch (error) { console.error("오류 발생:", error); }
}
// 함수 호출 fetchUserDataAndPosts().then(result => {
console.log("모든 작업 완료:", result);
});
// Promise.all - 여러 Promise를 병렬로 처리 async function fetchAllData() {
try { const [users, posts, comments] = await Promise.all([ fetchUsers(), fetchPosts(), fetchComments() ]); console.log(users, posts, comments); } catch (error) { console.error(error); }
} ```
모듈화
ES 모듈
```javascript // math.js (내보내기) export function add(a, b) {
return a + b;
}
export function subtract(a, b) {
return a - b;
}
export const PI = 3.14159;
export default class Calculator {
// 클래스 내용
}
// app.js (가져오기) import Calculator, { add, subtract, PI as MATH_PI } from './math.js';
console.log(add(5, 3)); // 8 console.log(subtract(10, 4)); // 6 console.log(MATH_PI); // 3.14159
const calc = new Calculator(); ```
HTML에서 모듈 사용
```html <script type="module" src="app.js"></script> ```
모범 사례와 디버깅
코딩 모범 사례
- 의미 있는 변수/함수 이름 사용
- let과 const 사용 (var 대신)
- 함수는 한 가지 일만 수행하도록 설계
- 코드 중복 방지
- 주석 작성 (필요한 경우)
- 일관된 코드 형식 유지
- 엄격 모드 사용: `"use strict";`
디버깅 도구
- console 메서드:
* console.log(): 일반 메시지 출력 * console.error(): 오류 메시지 출력 * console.warn(): 경고 메시지 출력 * console.table(): 표 형식으로 데이터 출력 * console.time() / console.timeEnd(): 코드 실행 시간 측정
- 브라우저 개발자 도구:
* 요소 검사 * 자바스크립트 디버거 (중단점 설정) * 네트워크 모니터링 * 성능 분석
학습 자료
- MDN Web Docs - JavaScript
- JavaScript.info
- W3Schools JavaScript Tutorial
- Eloquent JavaScript (무료 온라인 책)
- You Don't Know JS (무료 온라인 책)
다음 학습 단계
- HTML 기초: 웹 페이지 구조의 이해
- CSS 기초: 웹 페이지 스타일링
- JavaScript 프레임워크: React, Vue, Angular 등
- JavaScript 고급: 클로저, 프로토타입, 이벤트 루프 등
- Node.js: 서버 사이드 JavaScript 개발