본문 바로가기
IT/Javascript Basic

[javascript] 자바스크립트 중급 문법 학습 자료

by Echinacea 2025. 2. 9.
반응형

 

1. 스코프(Scope)와 호이스팅(Hoisting)

📌 스코프란?

  • 스코프는 변수에 접근할 수 있는 범위를 의미합니다.
  • 전역 스코프(Global Scope)와 지역 스코프(Local Scope)로 나뉩니다.

🔍 전역 스코프(Global Scope): 코드 어디서든 접근할 수 있는 범위

🔍 지역 스코프(Local Scope): 함수나 블록 내부에서만 접근할 수 있는 범위

✨ 전역 스코프 예제

var globalVar = "나는 전역 변수야!";

function showGlobal() {
    console.log(globalVar); // 어디서든 접근 가능
}

showGlobal(); // "나는 전역 변수야!"
console.log(globalVar); // "나는 전역 변수야!"

전역 변수는 프로그램 어디서든 접근이 가능하지만, 전역 변수를 많이 사용하면 유지보수가 어려워질 수 있습니다.


✨ 지역 스코프 예제

function showLocal() {
    let localVar = "나는 지역 변수야!";
    console.log(localVar); // 함수 내부에서만 접근 가능
}

showLocal(); // "나는 지역 변수야!"
console.log(localVar); // ReferenceError: localVar is not defined

지역 변수는 해당 함수나 블록 내부에서만 접근할 수 있으므로, 불필요한 변수 접근을 방지할 수 있습니다.


✨ 전역 스코프와 지역 스코프가 함께 사용된 예제

let globalMessage = "나는 전역 변수야!";

function displayMessage() {
    let localMessage = "나는 지역 변수야!";
    console.log(globalMessage); // 전역 변수 접근 가능
    console.log(localMessage); // 지역 변수 접근 가능
}

displayMessage();
console.log(globalMessage); // "나는 전역 변수야!"
console.log(localMessage); // ReferenceError: localMessage is not defined

함수 내부에서는 전역 변수와 지역 변수 모두 접근할 수 있지만, 함수 외부에서는 지역 변수에 접근할 수 없습니다.

📌 호이스팅이란?

  • 자바스크립트는 실행 전에 변수와 함수를 최상단으로 끌어올리는(Hoisting) 특징이 있습니다.
  • 하지만, letconst는 호이스팅되지만 초기화되지 않음에 유의해야 합니다.
    *"초기화되지 않는다"는 의미는 변수가 선언되었지만, 값이 할당되지 않았다는 뜻

✨ 예제 코드

console.log(a); // undefined (호이스팅 발생!)
var a = 10;

console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 20;

🏋️ 실습 문제

function test() {
    console.log(x);
    var x = 5;
}
test();

❓ 위 코드의 출력 결과는?

🔹 해답: undefined (변수 선언이 호이스팅되지만 값 할당은 이후에 일어남)


 

2. 함수 표현식과 화살표 함수

📌 함수 표현식 vs 함수 선언문

  • 함수 선언문은 호이스팅되지만, 함수 표현식은 그렇지 않습니다.

🔍 함수 선언문

function sayHello() {
    console.log("Hello!");
}

🔍 함수 표현식 (익명 함수)

const sayHello = function() {
    console.log("Hello!");
};

📌 화살표 함수(Arrow Function)

  • function 키워드 없이 간결하게 함수를 정의하는 문법입니다.
  • this를 바인딩하지 않음.

 


자바스크립트에서 **화살표 함수(arrow function)**는 기존의 function과 달리 this를 바인딩하지 않는다는 특징이 있습니다.
이 말이 의미하는 바를 쉽게 설명해볼게요. 😊


🔍 this 바인딩이란?

  • 일반적인 function에서는 this가 함수를 호출한 객체를 가리킵니다.
  • 하지만 화살표 함수는 자신만의 this를 가지지 않으며, 선언된 위치에서 this를 그대로 사용합니다.

📌 일반 함수의 this 동작

javascript
복사편집
const person = { name: "Alice", greet: function() { console.log(`Hello, my name is ${this.name}`); } }; person.greet(); // Hello, my name is Alice

✅ this가 person 객체를 가리키고 있기 때문에 this.name이 "Alice"가 됩니다.


📌 화살표 함수의 this 동작

javascript
복사편집
const person = { name: "Alice", greet: () => { console.log(`Hello, my name is ${this.name}`); } }; person.greet(); // Hello, my name is undefined

⛔ this.name이 undefined가 되는 이유:

  • 화살표 함수는 자신만의 this를 생성하지 않고, 바깥 스코프의 this를 가져옵니다.
  • 위 코드에서 greet() 함수는 person 객체 안에 있지만, this는 person을 가리키지 않고 **전역 객체(window 또는 global)**를 참조합니다.

📌 화살표 함수에서 this가 고정되는 예제

javascript
복사편집
const obj = { value: 42, method: function() { setTimeout(() => { console.log(this.value); // 42 }, 1000); } }; obj.method();

✅ 여기서 setTimeout() 내부의 this는 obj를 유지합니다.

  • 이유? setTimeout() 내부의 함수가 화살표 함수이기 때문입니다.
  • 일반 함수였다면, this는 undefined이거나 window를 가리켰을 것입니다.

🔥 결론

  • 일반 함수(function) → this가 호출한 객체를 가리킴.
  • 화살표 함수(=>) → this를 새롭게 바인딩하지 않고 선언된 위치의 this를 사용.

즉, 화살표 함수는 this를 바인딩하지 않고, 외부 스코프의 this를 유지한다! 🚀


 

 

 

🔍 예제 코드

const add = (a, b) => a + b;
console.log(add(5, 3)); // 8

🏋️ 실습 문제

❓ 다음 함수 표현식을 화살표 함수로 변환하세요.

const multiply = function(x, y) {
    return x * y;
};

🔹 해답:

const multiply = (x, y) => x * y;

 

3. 객체(Object)와 배열(Array)의 기초

📌 객체(Object)란?

  • 객체는 여러 개의 관련 데이터를 하나로 묶는 구조입니다.
  • key: value 형태로 데이터를 저장합니다.
  • 객체 내부에는 **변수(속성)**와 **함수(메서드)**를 포함할 수 있습니다.

🔍 객체 예제

const person = {
    name: "Alice",
    age: 25,
    greet: function() {
        console.log(`Hello, my name is ${this.name}`);
    }
};
console.log(person.name); // "Alice"
person.greet(); // "Hello, my name is Alice"

📌 객체 속성 추가 및 삭제

person.job = "Developer"; // 새 속성 추가
console.log(person.job); // "Developer"
delete person.age; // 속성 삭제
console.log(person.age); // undefined

📌 배열(Array)이란?

  • 배열은 순서가 있는 데이터의 목록입니다.
  • 여러 개의 값을 **인덱스(index)**를 사용하여 관리합니다.
  • 0부터 시작하는 숫자로 각 요소를 구분합니다.

🔍 배열 예제

const fruits = ["Apple", "Banana", "Cherry"];
console.log(fruits[0]); // "Apple"
console.log(fruits.length); // 3

📌 배열 요소 추가 및 삭제

fruits.push("Mango"); // 끝에 요소 추가
console.log(fruits); // ["Apple", "Banana", "Cherry", "Mango"]
fruits.pop(); // 끝 요소 제거
console.log(fruits); // ["Apple", "Banana", "Cherry"]

📌 배열과 객체의 차이점

  • 배열은 순서가 있는 데이터의 집합, 객체는 키-값 쌍으로 이루어진 데이터의 집합입니다.
  • 배열은 push(), pop() 등의 메서드로 다루며, 객체는 Object.keys(), Object.values() 같은 메서드를 사용합니다.

🔍 배열과 객체 비교

const student = {
    name: "John",
    age: 21
};

const students = ["John", "Jane", "Mark"];

 


 

4. 배열 메서드

📌 배열 메서드란?

  • 배열을 조작할 수 있도록 제공되는 기능들입니다.
  • 데이터를 추가, 삭제, 변형하는 데 사용됩니다.

🔍 요소 추가 및 제거 메서드

  • push(value): 배열 끝에 요소 추가
  • pop(): 배열 끝 요소 제거
  • unshift(value): 배열 앞에 요소 추가
  • shift(): 배열 앞 요소 제거
let numbers = [1, 2, 3];
numbers.push(4); // [1, 2, 3, 4]
numbers.pop(); // [1, 2, 3]
numbers.unshift(0); // [0, 1, 2, 3]
numbers.shift(); // [1, 2, 3]

🔍 배열 일부를 추출 및 변경하는 메서드

  • slice(start, end): 원본을 변경하지 않고 특정 부분을 추출
  • splice(start, deleteCount, item1, item2, ...): 원본을 변경하여 요소를 추가 또는 제거
let fruits = ["Apple", "Banana", "Cherry", "Date"];
console.log(fruits.slice(1, 3)); // ["Banana", "Cherry"]

fruits.splice(2, 1, "Orange");
console.log(fruits); // ["Apple", "Banana", "Orange", "Date"]

🔍 배열 변환 및 검색 메서드

  • map(callback): 각 요소에 함수를 적용하여 새로운 배열 반환
  • filter(callback): 조건을 만족하는 요소들만 새로운 배열로 반환
  • find(callback): 조건을 만족하는 첫 번째 요소 반환
  • includes(value): 특정 값이 포함되어 있는지 확인
let numbers2 = [1, 2, 3, 4, 5];
let squared = numbers2.map(num => num * num);
console.log(squared); // [1, 4, 9, 16, 25]

let evenNumbers = numbers2.filter(num => num % 2 === 0);
console.log(evenNumbers); // [2, 4]

let found = numbers2.find(num => num > 3);
console.log(found); // 4

console.log(numbers2.includes(3)); // true

🏋️ 실습 문제

arr = [10, 20, 30, 40, 50]에서 30 이상의 값만 필터링하는 코드를 작성하세요.

🔹 해답:

let arr = [10, 20, 30, 40, 50];
let filteredArr = arr.filter(num => num >= 30);
console.log(filteredArr); // [30, 40, 50]

 

5. ES6+ 문법

📌 ES6(ECMAScript 2015)란?

  • 자바스크립트의 주요 업데이트 중 하나로, 기존 ES5보다 더욱 강력한 기능들을 포함하고 있습니다.
  • 코드의 가독성을 높이고 유지보수를 쉽게 해주는 다양한 문법이 포함됩니다.

🔍 letconst - 새로운 변수 선언 방법

  • var를 대체하는 두 가지 새로운 변수 선언 방식입니다.
  • let재할당 가능, const재할당 불가능합니다.
let x = 10;
const y = 20;
y = 30; // 오류 발생! (const는 재할당 불가능)

📌 var 대신 letconst를 사용할까요?

  • var는 함수 스코프를 가지며, 의도치 않은 변수 변경이 발생할 수 있습니다.
  • letconst는 블록 스코프를 가지므로, 변수를 안전하게 관리할 수 있습니다.

🔍 템플릿 리터럴(Template Literal)

  • 백틱(`)을 사용하여 문자열을 보다 쉽게 조작할 수 있습니다.
  • 문자열 내부에서 변수를 사용할 때 ${변수} 문법을 활용할 수 있습니다.
const name = "Alice";
console.log(`Hello, ${name}!`); // Hello, Alice!

📌 왜 템플릿 리터럴을 사용할까요?

  • 기존의 문자열 결합(+)보다 가독성이 좋아집니다.
  • 여러 줄 문자열을 쉽게 작성할 수 있습니다.
const message = `안녕하세요,
저는 Alice입니다.
자바스크립트를 공부 중이에요!`;
console.log(message);

🔍 디스트럭처링 할당(Destructuring Assignment)

  • 객체나 배열에서 값을 쉽게 추출할 수 있는 문법입니다.

🔹 객체 디스트럭처링

const person = { name: "Bob", age: 30 };
const { name, age } = person;
console.log(name, age); // Bob 30

🔹 배열 디스트럭처링

const numbers = [1, 2, 3];
const [first, second] = numbers;
console.log(first, second); // 1 2

📌 디스트럭처링 할당의 장점

  • 코드를 더욱 짧고 읽기 쉽게 만들어 줍니다.
  • 변수 할당을 직관적으로 할 수 있습니다.

🏋️ 실습 문제

const user = { firstName: "John", lastName: "Doe" } 객체에서 firstNamelastName을 디스트럭처링으로 추출하여 콘솔에 출력하는 코드를 작성하세요.

🔹 해답:

const user = { firstName: "John", lastName: "Doe" };
const { firstName, lastName } = user;
console.log(firstName, lastName); // John Doe

📌 ES6+ 문법을 익히면 더욱 깔끔하고 유지보수하기 좋은 코드를 작성할 수 있습니다! 🚀


📝 마무리

  • 스코프와 호이스팅을 이해하면 변수의 동작을 예측하기 쉬워집니다.
  • 함수 표현식과 화살표 함수는 가독성을 높여 줍니다.
  • 객체와 배열을 다룰 줄 알면 데이터 처리가 쉬워집니다.
  • 배열 메서드를 활용하면 데이터를 효율적으로 조작할 수 있습니다.
  • ES6+ 문법을 익히면 코드가 더 간결해집니다.

💡 실전 팁

  • 코드를 작성할 때 var 대신 letconst를 사용하세요.
  • 함수 내부에서 this를 사용할 때, 화살표 함수와 일반 함수의 차이를 이해하세요.
  • 배열 메서드를 적극적으로 활용하여 데이터를 효율적으로 조작하세요.
  • ES6+ 문법을 익히고 적극 활용하면 가독성이 높고 유지보수하기 좋은 코드를 작성할 수 있습니다.

실습 문제를 직접 풀어보며 개념을 확실히 익히세요!

반응형

댓글