JavaScript Syntax
자바스크립트 문법 (JavaScript Syntax) 완벽 가이드
- *자바스크립트(JavaScript)**는 현대 웹 개발에서 필수적인 프로그래밍 언어로, 웹 페이지에 동적 기능과 상호작용을 추가하는 데 사용됩니다. 이 가이드에서는 자바스크립트의 기본 문법부터 고급 문법까지 체계적으로 설명하여, 효과적인 웹 개발을 위한 탄탄한 기초를 다질 수 있도록 도와드립니다.
자바스크립트 문법이란?
자바스크립트 문법은 자바스크립트 언어를 사용하여 프로그램을 작성할 때 따라야 하는 규칙과 구조를 의미합니다. 문법은 프로그램의 구조를 정의하며, 올바른 문법을 따르지 않으면 코드가 제대로 실행되지 않습니다. 자바스크립트 문법을 이해하는 것은 효율적이고 오류 없는 코드를 작성하는 데 필수적입니다.
기본 문법 요소
변수 선언
자바스크립트에서는 변수를 선언할 때 var
, let
, const
키워드를 사용합니다. 각 키워드는 변수의
스코프(scope)와 재할당 가능 여부에 따라 다르게 동작합니다.
// var를 사용한 변수 선언 (전역 또는 함수 스코프)
var globalVar = "전역 변수";
// let을 사용한 변수 선언 (블록 스코프)
let blockVar = "블록 변수";
// const를 사용한 상수 선언 (블록 스코프, 재할당 불가)
const PI = 3.14159;
- var
- 함수 스코프를 가집니다.
- 재선언과 재할당이 가능합니다.
- let
- 블록 스코프를 가집니다.
- 재선언은 불가능하지만 재할당은 가능합니다.
- const
- 블록 스코프를 가집니다.
- 재선언과 재할당이 모두 불가능합니다.
데이터 타입
자바스크립트는 동적 타이핑(Dynamic Typing) 언어로, 변수의 타입을 명시적으로 선언하지 않고도 사용할 수 있습니다. 주요 데이터 타입은 다음과 같습니다:
- 원시 타입 (Primitive Types)
Number
: 숫자 (예:42
,3.14
)String
: 문자열 (예:"Hello, World!"
)Boolean
: 불리언 (예:true
,false
)Undefined
: 정의되지 않음Null
: 널 값Symbol
: 고유하고 변경 불가능한 값BigInt
: 큰 정수
- 참조 타입 (Reference Types)
Object
: 객체 (예:{ name: "Alice", age: 25 }
)Array
: 배열 (예:[1, 2, 3]
)Function
: 함수
let number = 42; // Number
let greeting = "Hello"; // String
let isStudent = true; // Boolean
let nothing = null; // Null
let notDefined; // Undefined
let uniqueId = Symbol("id"); // Symbol
let bigNumber = 9007199254740991n; // BigInt
let person = {
name: "Alice",
age: 25
}; // Object
let fruits = ["Apple", "Banana", "Cherry"]; // Array
function greet() {
console.log("Hi!");
} // Function
연산자
자바스크립트는 다양한 연산자를 제공하여 변수와 값을 조작할 수 있습니다. 주요 연산자는 다음과 같습니다:
- 산술 연산자 (Arithmetic Operators)
+
,,
,/
,%
,++
,-
- 대입 연산자 (Assignment Operators)
=
,+=
,=
,=
,/=
,%=
- 비교 연산자 (Comparison Operators)
==
,===
,!=
,!==
,>
,<
,>=
,<=
- 논리 연산자 (Logical Operators)
&&
(AND),||
(OR),!
(NOT)
- 비트 연산자 (Bitwise Operators)
&
,|
,^
,~
,<<
,>>
,>>>
- 기타 연산자
typeof
,instanceof
,? :
(삼항 연산자)
let a = 10;
let b = 5;
// 산술 연산자
let sum = a + b; // 15
let difference = a - b; // 5
let product = a * b; // 50
let quotient = a / b; // 2
let remainder = a % b; // 0
// 대입 연산자
a += 5; // a = 15
b *= 2; // b = 10
// 비교 연산자
console.log(a > b); // true
console.log(a === b); // false
// 논리 연산자
console.log(a > b && b > 0); // true
console.log(a < b || b === 10); // true
// 삼항 연산자
let result = (a > b) ? "a가 큽니다." : "b가 큽니다.";
console.log(result); // "a가 큽니다."
제어 흐름
프로그램의 실행 흐름을 제어하기 위해 조건문과 반복문을 사용합니다.
조건문
조건문은 특정 조건에 따라 코드 블록의 실행 여부를 결정합니다. 주요 조건문은 if
, else if
,
else
, switch
입니다.
if-else
문
let score = 85;
if (score >= 90) {
console.log("A 등급");
} else if (score >= 80) {
console.log("B 등급");
} else {
console.log("C 등급");
}
// 출력: B 등급
switch
문
let day = "월요일";
switch(day) {
case "월요일":
console.log("출근일");
break;
case "금요일":
console.log("퇴근일");
break;
default:
console.log("평일");
}
// 출력: 출근일
반복문
반복문은 특정 조건이 만족되는 동안 코드 블록을 반복 실행합니다. 주요 반복문은 for
, while
,
do...while
, for...of
, for...in
입니다.
for
문
for (let i = 0; i < 5; i++) {
console.log("반복 횟수:", i);
}
// 출력:
// 반복 횟수: 0
// 반복 횟수: 1
// 반복 횟수: 2
// 반복 횟수: 3
// 반복 횟수: 4
while
문
let i = 0;
while (i < 5) {
console.log("반복 횟수:", i);
i++;
}
// 출력과 동일
do...while
문
let i = 0;
do {
console.log("반복 횟수:", i);
i++;
} while (i < 5);
// 출력과 동일
for...of
문
let fruits = ["사과", "바나나", "오렌지"];
for (let fruit of fruits) {
console.log(fruit);
}
// 출력:
// 사과
// 바나나
// 오렌지
for...in
문
let person = { name: "Alice", age: 25, city: "Seoul" };
for (let key in person) {
console.log(key + ": " + person[key]);
}
// 출력:
// name: Alice
// age: 25
// city: Seoul
함수 선언
함수는 재사용 가능한 코드 블록으로, 특정 작업을 수행하도록 정의됩니다. 자바스크립트에서는 함수 선언식, 함수 표현식, 화살표 함수 등을 사용하여 함수를 정의할 수 있습니다.
함수 선언식과 표현식
함수 선언식
function greet(name) {
return `안녕하세요, ${name}!`;
}
let message = greet("Bob");
console.log(message); // 출력: 안녕하세요, Bob!
함수 표현식
const greet = function(name) {
return `안녕하세요, ${name}!`;
};
let message = greet("Bob");
console.log(message); // 출력: 안녕하세요, Bob!
화살표 함수
- *화살표 함수(Arrow Function)**는 더 간결한 함수 표현식을 제공합니다.
// 기존 함수 표현식
function add(a, b) {
return a + b;
}
// 화살표 함수 표현식
const add = (a, b) => a + b;
console.log(add(2, 3)); // 출력: 5
- 장점
- 더 짧은 문법
this
바인딩이 정적으로 결정됨
- 주의 사항
this
가 기존 함수와 다르게 동작할 수 있음- 생성자 함수로 사용할 수 없음
객체와 배열
객체 리터럴
- *객체(Object)**는 키-값 쌍의 집합으로, 관련된 데이터를 그룹화할 때 사용됩니다.
const person = {
name: "Alice",
age: 25,
greet: function() {
console.log(`안녕하세요, 제 이름은 ${this.name}입니다.`);
}
};
console.log(person.name); // 출력: Alice
person.greet(); // 출력: 안녕하세요, 제 이름은 Alice입니다.
배열 리터럴
- *배열(Array)**은 순서가 있는 데이터의 목록을 저장하는 데 사용됩니다.
const fruits = ["사과", "바나나", "오렌지"];
console.log(fruits[0]); // 출력: 사과
fruits.push("포도"); // 배열에 요소 추가
console.log(fruits); // 출력: ["사과", "바나나", "오렌지", "포도"]
- 주요 메서드
push()
,pop()
,shift()
,unshift()
,splice()
,slice()
,forEach()
,map()
,filter()
,reduce()
클래스와 상속
- *클래스(Class)**는 객체 지향 프로그래밍(OOP)에서 템플릿으로 사용되며, 객체를 생성하기 위한 청사진을 제공합니다. 자바스크립트는 ES6부터 클래스 문법을 도입하여 더 직관적인 객체 지향 프로그래밍을 지원합니다.
클래스 선언
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
console.log(`안녕하세요, 제 이름은 ${this.name}이고, 나이는 ${this.age}살입니다.`);
}
}
const person1 = new Person("Bob", 28);
person1.greet(); // 출력: 안녕하세요, 제 이름은 Bob이고, 나이는 28살입니다.
상속
클래스 상속을 통해 기존 클래스의 속성과 메서드를 물려받을 수 있습니다.
class Employee extends Person {
constructor(name, age, position) {
super(name, age);
this.position = position;
}
work() {
console.log(`${this.name}은(는) ${this.position}로 일하고 있습니다.`);
}
}
const employee1 = new Employee("Charlie", 30, "개발자");
employee1.greet(); // 출력: 안녕하세요, 제 이름은 Charlie이고, 나이는 30살입니다.
employee1.work(); // 출력: Charlie은(는) 개발자로 일하고 있습니다.
super
: 부모 클래스의 생성자나 메서드를 호출할 때 사용됩니다.- 메서드 오버라이딩: 자식 클래스에서 부모 클래스의 메서드를 재정의할 수 있습니다.
비동기 문법
자바스크립트는 비동기 프로그래밍을 지원하여, 긴 작업(예: 네트워크 요청, 파일 읽기 등)이 완료될 때까지 다른 작업을 차단하지 않고 실행될 수 있도록 합니다. 비동기 프로그래밍을 통해 웹 애플리케이션의 응답성을 향상시킬 수 있습니다.
Promise
Promise는 비동기 작업의 완료 또는 실패를 나타내는 객체입니다. then()
,
catch()
, finally()
메서드를 사용하여 비동기 작업의 결과를 처리할 수 있습니다.
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
let success = true;
if (success) {
resolve({ name: "Alice", age: 25 });
} else {
reject("데이터를 가져오는데 실패했습니다.");
}
}, 2000);
});
}
fetchData()
.then(data => {
console.log("데이터를 받았습니다:", data);
})
.catch(error => {
console.log("에러:", error);
});
async/await
async
와 await
키워드를 사용하면 Promise 기반의 비동기 코드를 동기식 코드처럼 작성할 수 있습니다. 이는 코드의
가독성을 높이고, 비동기 흐름을 쉽게 관리할 수 있게 합니다.
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
let success = true;
if (success) {
resolve({ name: "Alice", age: 25 });
} else {
reject("데이터를 가져오는데 실패했습니다.");
}
}, 2000);
});
}
async function getData() {
try {
let data = await fetchData();
console.log("데이터를 받았습니다:", data);
} catch (error) {
console.log("에러:", error);
}
}
getData();
async
함수: 항상 Promise를 반환하며, 함수 내부에서await
키워드를 사용할 수 있습니다.await
: Promise가 해결될 때까지 함수 실행을 일시 중지합니다.
기타 문법 요소
템플릿 리터럴
- *템플릿 리터럴(Template Literals)**은 **백틱(``` )**을 사용하여 문자열을 정의하고, 변수나 표현식을 쉽게 삽입할 수 있는 방법을 제공합니다.
let name = "John";
let age = 30;
// 기존 문자열 연결 방식
let message = "이름: " + name + ", 나이: " + age + "살";
// 템플릿 리터럴 사용
let messageTemplate = `이름: ${name}, 나이: ${age}살`;
console.log(messageTemplate); // 출력: 이름: John, 나이: 30살
- 다중 행 문자열: 여러 줄에 걸친 문자열을 쉽게 작성할 수 있습니다.
let multiLine = `이것은
여러 줄에 걸친
문자열입니다.`;
console.log(multiLine);
// 출력:
// 이것은
// 여러 줄에 걸친
// 문자열입니다.
비구조화 할당
- *비구조화 할당(Destructuring Assignment)**을 사용하면 배열이나 객체의 값을 간편하게 변수에 할당할 수 있습니다.
// 배열 비구조화
let [a, b] = [1, 2];
console.log(a); // 출력: 1
console.log(b); // 출력: 2
// 객체 비구조화
let person = { name: "Alice", age: 25 };
let { name, age } = person;
console.log(name); // 출력: Alice
console.log(age); // 출력: 25
- 기본값 설정: 변수에 기본값을 설정할 수 있습니다.
let [x = 10, y = 20] = [5];
console.log(x); // 출력: 5
console.log(y); // 출력: 20
let { a = 1, b = 2 } = { a: 3 };
console.log(a); // 출력: 3
console.log(b); // 출력: 2
예외 처리
- *예외 처리(Exception Handling)**는 코드 실행 중 발생할 수 있는 오류를 예측하고 대응하는 방법입니다. 자바스크립트는
try
,catch
,finally
,throw
문을 통해 예외를 처리합니다.
try-catch-finally
문
try {
let result = 10 / 0;
console.log(result);
} catch (error) {
console.log("오류 발생:", error.message);
} finally {
console.log("예외 처리 완료");
}
// 출력:
// Infinity
// 예외 처리 완료
throw
문
function validateAge(age) {
if (age < 18) {
throw new Error("미성년자는 접근할 수 없습니다.");
}
console.log("성인입니다.");
}
try {
validateAge(16);
} catch (error) {
console.log("오류:", error.message);
}
// 출력:
// 오류: 미성년자는 접근할 수 없습니다.
throw
: 의도적으로 예외를 발생시킬 때 사용합니다.catch
: 발생한 예외를 잡아 처리합니다.finally
: 예외 발생 여부와 관계없이 항상 실행되는 블록입니다.
모듈화
자바스크립트는 **모듈(Module)**을 사용하여 코드의 재사용성과 유지보수성을 높일 수 있습니다. ES6부터 import
와 export
키워드를 사용한 모듈
시스템이 도입되었습니다.
모듈 가져오기 및 내보내기
모듈 내보내기 (export
)
// math.js
export function add(a, b) {
return a + b;
}
export const PI = 3.14159;
모듈 가져오기 (import
)
// main.js
import { add, PI } from './math.js';
console.log(add(2, 3)); // 출력: 5
console.log(PI); // 출력: 3.14159
- 기본 내보내기: 하나의 값을 기본으로 내보낼 때 사용합니다.
// greet.js
export default function greet(name) {
return `안녕하세요, ${name}!`;
}
// main.js
import greet from './greet.js';
console.log(greet("Bob")); // 출력: 안녕하세요, Bob!
- 별칭 사용: 모듈을 가져올 때 이름을 변경할 수 있습니다.
import { add as sum } from './math.js';
console.log(sum(4, 5)); // 출력: 9
ES6+ 특징
- *ECMAScript 2015(ES6)**는 자바스크립트의 주요 업데이트로, 다양한 새로운 기능과 개선 사항을 도입했습니다. ES6 이후에도 ECMAScript는 지속적으로 업데이트되며, 최신 자바스크립트 기능을 사용하면 코드의 가독성과 효율성을 높일 수 있습니다.
주요 ES6+ 기능
- 화살표 함수 (Arrow Functions)
- 템플릿 리터럴 (Template Literals)
- 비구조화 할당 (Destructuring Assignment)
- 클래스 (Classes)
- 모듈 (Modules)
- 프라미스 (Promises)
- 기본 매개변수 (Default Parameters)
- 스프레드 연산자 (Spread Operator)
- 레스트 파라미터 (Rest Parameters)
- 이터레이터와 제너레이터 (Iterators and Generators)
- Symbol
- Map과 Set
- 블록 스코프 변수 (let and const)
- 기타 최신 기능들
문법 오류와 디버깅
문법 오류
- *문법 오류(Syntax Errors)**는 코드가 자바스크립트 문법을 준수하지 않을 때 발생합니다. 이러한 오류는 코드 실행 전에 컴파일러가 감지하며, 오류 메시지를 통해 문제를 알려줍니다.
예시: 누락된 괄호
function greet(name) {
console.log("Hello, " + name;
}
greet("Alice");
// SyntaxError: missing ) after argument list
디버깅
- *디버깅(Debugging)**은 코드의 오류를 찾아 수정하는 과정입니다. 자바스크립트에서는 브라우저의 개발자 도구를 활용하여 디버깅을 수행할 수 있습니다.
주요 디버깅 도구
- Console:
console.log()
,console.error()
등을 사용하여 변수 값과 메시지를 출력. - Breakpoints: 코드 실행을 특정 지점에서 일시 중지하여 상태를 검사.
- Watch Expressions: 특정 변수나 표현식의 값을 실시간으로 모니터링.
- Call Stack: 함수 호출의 순서를 추적.
예시: 브라우저 디버깅
- 개발자 도구 열기:
F12
키 또는Ctrl+Shift+I
단축키 사용. - Console 탭:
console.log()
를 사용하여 변수 값을 확인. - Sources 탭: 브레이크포인트를 설정하고, 코드 실행을 단계별로 추적.
function calculateTotal(price, quantity) {
let total = price * quantity;
console.log("총 합계:", total);
return total;
}
calculateTotal(100, 5);
요약
- 자바스크립트 문법은 변수 선언, 데이터 타입, 연산자, 제어 흐름, 함수 선언, 객체와 배열, 클래스와 상속, 비동기 문법, 기타 문법 요소 등 다양한 요소로 구성됩니다.
- 제어 흐름을 통해 프로그램의 실행 흐름을 조건에 따라 변경하거나 반복할 수 있습니다.
- 함수는 코드의 재사용성을 높이고, 객체와 배열은 데이터를 효율적으로 관리하는 데 사용됩니다.
- 클래스와 상속을 통해 객체 지향 프로그래밍을 구현할 수 있으며, 비동기 문법을 통해 웹 애플리케이션의 응답성을 향상시킬 수 있습니다.
- 모듈화를 통해 코드의 재사용성과 유지보수성을 높일 수 있으며, **ES6+**의 다양한 기능을 활용하여 현대적인 자바스크립트 코드를 작성할 수 있습니다.
- 문법 오류와 디버깅을 통해 코드의 안정성을 확보하고, 개발자 도구를 활용하여 효율적으로 문제를 해결할 수 있습니다.
자바스크립트의 다양한 문법과 기능을 숙지하고, 실제 프로젝트에 적용함으로써 효율적이고 안정적인 웹 애플리케이션을 개발할 수 있습니다. 꾸준한 연습과 학습을 통해 자바스크립트 마스터의 길을 걸어보세요!
JavaScript의 문법을 잘 이해하고 활용하면, 더 나은 웹 개발자로 성장할 수 있습니다. 이 가이드를 바탕으로 자바스크립트의 다양한 문법 요소를 익히고, 실무에 적용해보세요!