🎨 Frontend

πŸ“˜ μžλ°”μŠ€ν¬λ¦½νŠΈ(JavaScript) κΈ°λ³Έ λ‹€μ§€κΈ° - Part 2

hyebin (Helia) 2025. 4. 27. 15:39
λ°˜μ‘ν˜•

ν•¨μˆ˜, 객체/λ°°μ—΄, DOM, this, μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ μ™„μ „ 정볡

 

μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ κΈ°λ³ΈκΈ°λ₯Ό 더 νƒ„νƒ„ν•˜κ²Œ λ§Œλ“€κΈ° μœ„ν•΄, 이번 κΈ€μ—μ„œλŠ” μ‹€λ¬΄μ—μ„œ 자주 λ§ˆμ£ΌμΉ˜λŠ” 핡심 μ£Όμ œλ“€μ„ λ‹€λ€„λ³Όκ²Œμš”.

ν•¨μˆ˜μ˜ μ„ μ–Έ 방식뢀터, 객체와 λ°°μ—΄μ˜ ν™œμš©, DOM μ‘°μž‘, 그리고 λ§Žμ€ κ°œλ°œμžκ°€ μ²˜μŒμ— ν—·κ°ˆλ €ν•˜λŠ” this, μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκΉŒμ§€ ν•¨κ»˜ 정리해 λ³΄κ² μŠ΅λ‹ˆλ‹€.


βœ… ν•¨μˆ˜μ˜ λ‹€μ–‘ν•œ μ„ μ–Έ 방식

μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ ν•¨μˆ˜λ₯Ό μ„ μ–Έν•˜λŠ” 방식은 크게 μ„Έ κ°€μ§€κ°€ μžˆμ–΄μš”.

πŸ”Ή ν•¨μˆ˜ 선언식 (Function Declaration)

function sayHello() {
  console.log("μ•ˆλ…•ν•˜μ„Έμš”!");
}
sayHello(); // βœ… μ„ μ–Έ 전에도 호좜 κ°€λŠ₯
  • μ„ μ–Έ 전에 ν˜ΈμΆœν•΄λ„ μž‘λ™ν•΄μš”.
  • μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진이 μ‹€ν–‰ 전에 ν•¨μˆ˜ 선언을 ν˜Έμ΄μŠ€νŒ…(λŒμ–΄μ˜¬λ¦Ό) ν•˜κΈ° λ•Œλ¬Έμ΄μ—μš”.

πŸ”Ή ν•¨μˆ˜ ν‘œν˜„μ‹ (Function Expression)

const sayHi = function() {
  console.log("μ•ˆλ…•!");
};
sayHi(); // βœ… 호좜 κ°€λŠ₯ (단, μ„ μ–Έ 이후뢀터)
  • λ³€μˆ˜μ— ν•¨μˆ˜λ₯Ό μ €μž₯ν•˜λŠ” 방식이고, μ„ μ–Έ μ΄μ „μ—λŠ” ν˜ΈμΆœν•  수 μ—†μ–΄μš”.

πŸ”Ή ν™”μ‚΄ν‘œ ν•¨μˆ˜ (Arrow Function, ES6+)

const greet = (name) => {
  console.log(`μ•ˆλ…•, ${name}!`);
};

// 더 κ°„κ²°ν•˜κ²Œ (ν•œ 쀄일 경우 return μƒλž΅ κ°€λŠ₯)
const add = (a, b) => a + b;
ν•¨μˆ˜ μœ ν˜• ν˜Έμ΄μŠ€νŒ… this 바인딩 νŠΉμ§•
ν•¨μˆ˜ 선언식 O 자체 this μ„ μ–Έ 전에도 호좜 κ°€λŠ₯
ν•¨μˆ˜ ν‘œν˜„μ‹ X 자체 this λ³€μˆ˜μ— ν• λ‹Ήλœ ν˜•νƒœ, μ„ μ–Έ ν›„ 호좜
ν™”μ‚΄ν‘œ ν•¨μˆ˜ X μƒμœ„ μŠ€μ½”ν”„ this κ°„κ²°ν•œ λ¬Έλ²•, μƒμœ„ μŠ€μ½”ν”„μ˜ this μ‚¬μš©

βœ… 객체와 λ°°μ—΄μ˜ ν™œμš©

객체(Object)λŠ” key-value 쌍으둜 이루어진 자료 κ΅¬μ‘°μ˜ˆμš”.

const user = {
  name: "혜빈",
  age: 26,
  sayHello: function() {
    console.log(`μ•ˆλ…•ν•˜μ„Έμš”, ${this.name}μž…λ‹ˆλ‹€.`);
  },
};

user.sayHello(); // μ•ˆλ…•ν•˜μ„Έμš”, ν˜œλΉˆμž…λ‹ˆλ‹€.

이처럼 객체 μ•ˆμ—λŠ” 데이터뿐 μ•„λ‹ˆλΌ ν•¨μˆ˜λ„ 담을 수 μžˆμ–΄μš”. 이 ν•¨μˆ˜λŠ” 보톡 λ©”μ„œλ“œλΌκ³  λΆˆλŸ¬μš”.

// 객체 속성 μ ‘κ·Ό
console.log(user.name); // 혜빈
console.log(user['age']); // 26

// 객체 속성 μΆ”κ°€/μˆ˜μ •
user.job = '개발자';
user.age = 27;

// 객체 속성 μ‚­μ œ
delete user.age;

// 객체 λ©”μ„œλ“œ κ°„νŽΈ ν‘œκΈ°λ²• (ES6+)
const enhancedUser = {
  name: "λ―Όμ§€",
  greet() { // function ν‚€μ›Œλ“œ μƒλž΅ κ°€λŠ₯
    console.log(`Hello, I'm ${this.name}`);
  }
};

πŸ”Ή λ°°μ—΄ (Array)

λ°°μ—΄(Array)은 μˆœμ„œκ°€ μžˆλŠ” κ°’λ“€μ˜ μ§‘ν•©μ΄μ—μš”.

const fruits = ["사과", "λ°”λ‚˜λ‚˜", "포도"];

console.log(fruits[1]); // λ°”λ‚˜λ‚˜
fruits.push("λ”ΈκΈ°"); // λ°°μ—΄ 끝에 μΆ”κ°€

// λ°°μ—΄ μš”μ†Œ 순회
for (let i = 0; i < fruits.length; i++) {
  console.log(fruits[i]);
}

// for...of ꡬ문 (ES6+)
for (const fruit of fruits) {
  console.log(fruit);
}

자주 μ‚¬μš©ν•˜λŠ” λ°°μ—΄ λ©”μ„œλ“œ

  • map: λ°°μ—΄μ˜ 각 μš”μ†Œλ₯Ό λ³€ν˜•ν•΄ μƒˆ λ°°μ—΄ 생성
  • filter: 쑰건을 λ§Œμ‘±ν•˜λŠ” μš”μ†Œλ§Œ 남긴 μƒˆ λ°°μ—΄ 생성
  • reduce: λ°°μ—΄μ˜ 값을 ν•˜λ‚˜λ‘œ μ€„μž„ (λˆ„μ  계산)
  • forEach: 각 μš”μ†Œμ— λŒ€ν•΄ ν•¨μˆ˜ μ‹€ν–‰ (λ°˜ν™˜ κ°’μ—†μŒ)
  • find: 쑰건을 λ§Œμ‘±ν•˜λŠ” 첫 번째 μš”μ†Œ λ°˜ν™˜
const nums = [1, 2, 3, 4, 5];

const doubled = nums.map(n => n * 2);       // [2, 4, 6, 8, 10]
const odd = nums.filter(n => n % 2 === 1);  // [1, 3, 5]
const sum = nums.reduce((acc, curr) => acc + curr, 0); // 15
nums.forEach(n => console.log(n));
const found = nums.find(n => n > 3);  // 4
더보기

기타 λ°°μ—΄ λ©”μ„œλ“œ

 

λ©”μ„œλ“œ μš©λ„ λ°˜ν™˜κ°’ 원본 λ°°μ—΄ λ³€κ²½
push/pop 끝에 μΆ”κ°€/제거 μƒˆ 길이/제거된 μš”μ†Œ O
shift/unshift μ•žμ— 제거/μΆ”κ°€ 제거된 μš”μ†Œ/μƒˆ 길이 O
map 각 μš”μ†Œ λ³€ν™˜ μƒˆ λ°°μ—΄ X
filter 쑰건 필터링 μƒˆ λ°°μ—΄ X
reduce κ°’ λˆ„μ  계산 계산 κ²°κ³Ό X
forEach 각 μš”μ†Œ 순회 undefined X
slice 일뢀 μΆ”μΆœ μƒˆ λ°°μ—΄ X
splice μš”μ†Œ ꡐ체 제거된 μš”μ†Œ λ°°μ—΄ O
 

βœ… DOM μ‘°μž‘ (Document Object Model)

μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” HTML λ¬Έμ„œ(=DOM)λ₯Ό μ‘°μž‘ν•  수 μžˆμ–΄μš”.

ν™”λ©΄μ˜ ν…μŠ€νŠΈλ₯Ό λ°”κΎΈκ±°λ‚˜, μš”μ†Œλ₯Ό ν΄λ¦­ν–ˆμ„ λ•Œ 이벀트λ₯Ό μ²˜λ¦¬ν•  수 있죠.

πŸ”Ή μš”μ†Œ 선택

const title = document.getElementById("main-title");
const buttons = document.querySelectorAll(".btn");

πŸ”Ή ν…μŠ€νŠΈ, 속성 λ³€κ²½

title.textContent = "μƒˆλ‘œμš΄ 제λͺ©";
title.setAttribute("data-role", "hero");

πŸ”Ή ν΄λž˜μŠ€ μ œμ–΄

title.classList.add("active");
title.classList.remove("hidden");

πŸ”Ή μ΄λ²€νŠΈ λ¦¬μŠ€λ„ˆ μΆ”κ°€

const btn = document.querySelector(".btn");

btn.addEventListener("click", () => {
  alert("λ²„νŠΌμ΄ ν΄λ¦­λ˜μ—ˆμŠ΅λ‹ˆλ‹€!");
});

μ΄λ ‡κ²Œ ν•˜λ©΄ HTMLκ³Ό μžλ°”μŠ€ν¬λ¦½νŠΈκ°€ μ—°κ²°λ˜μ–΄ μ§„μ§œλ‘œ λ™μž‘ν•˜λŠ” νŽ˜μ΄μ§€λ₯Ό λ§Œλ“€ 수 있게 λΌμš”.


 

βœ… μžλ°”μŠ€ν¬λ¦½νŠΈ μ‹€ν–‰ 방식 μ΄ν•΄ν•˜κΈ°

μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” μ½”λ“œκ°€ μ‹€ν–‰λ˜κΈ° 전에 λ‚΄λΆ€μ μœΌλ‘œ λ‹€μ–‘ν•œ 과정을 κ±°μ³μš”.

κ·Έ 과정을 μ•Œλ©΄ 버그λ₯Ό 쀄이고, μ½”λ“œλ₯Ό 더 μ •ν™•ν•˜κ²Œ μ˜ˆμΈ‘ν•  수 μžˆμ–΄μš”.

1. ν˜Έμ΄μŠ€νŒ…(Hoisting)

μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” μ‹€ν–‰ 전에 λ³€μˆ˜μ™€ ν•¨μˆ˜ 선언을 λ¨Όμ € λŒμ–΄μ˜¬λ¦¬λŠ” μž‘μ—…μ„ ν•΄μš”.

이걸 ν˜Έμ΄μŠ€νŒ…μ΄λΌκ³  ν•΄μš”.

console.log(x); // undefined
var x = 10;

μ΄λ ‡κ²Œ var둜 μ„ μ–Έν•œ λ³€μˆ˜λŠ” μ„ μ–Έλ§Œ μœ„λ‘œ μ˜¬λΌκ°€κ³ , 값은 ν• λ‹Ήλ˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— undefinedκ°€ 좜λ ₯λΌμš”.

반면 let, constλŠ” μ΄ˆκΈ°ν™” 전에 μ ‘κ·Όν•˜λ©΄ μ—λŸ¬κ°€ λ°œμƒν•΄μš”.

2. this ν‚€μ›Œλ“œ

thisλŠ” ν˜„μž¬ μ‹€ν–‰ 쀑인 λ¬Έλ§₯(context)에 따라 λ‹¬λΌμ§€λŠ” ν‚€μ›Œλ“œμ˜ˆμš”.

const person = {
  name: "혜빈",
  sayHello() {
    console.log(this.name);
  }
};

person.sayHello(); // '혜빈'

μ—¬κΈ°μ„œλŠ” thisκ°€ person 객체λ₯Ό κ°€λ¦¬μΌœμš”.

ν•˜μ§€λ§Œ μ•„λž˜μ²˜λŸΌ ν•¨μˆ˜λ§Œ λ”°λ‘œ κΊΌλ‚΄μ„œ μ“°λ©΄ λ‹¬λΌμ Έμš”.

const greet = person.sayHello;
greet(); // undefined (λΈŒλΌμš°μ € ν™˜κ²½μ—μ„œλŠ” window.name)

λ˜ν•œ ν™”μ‚΄ν‘œ ν•¨μˆ˜λŠ” thisλ₯Ό λ°”μΈλ”©ν•˜μ§€ μ•Šκ³ , μžμ‹ μ΄ μ„ μ–Έλœ μœ„μΉ˜μ˜ thisλ₯Ό κ·ΈλŒ€λ‘œ μ‚¬μš©ν•΄μš”.

3. μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ(Execution Context)

μ½”λ“œκ°€ μ‹€ν–‰λ˜κΈ° μ „, μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 μ‹€ν–‰ ν™˜κ²½μ„ κ΅¬μ„±ν•΄μš”. 이걸 μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλΌκ³  λΆ€λ¦…λ‹ˆλ‹€.

μ‰½κ²Œ λ§ν•˜λ©΄, λˆ„κ°€ μ‹€ν–‰ 쀑인지, μ–΄λ–€ λ³€μˆ˜λ“€μ΄ μžˆλŠ”μ§€, μ–΄λ–€ ν•¨μˆ˜κ°€ 어디에 μžˆλŠ”μ§€λ₯Ό κΈ°μ–΅ν•˜λŠ” κ³΅κ°„μ΄μ—μš”.

function outer() {
  const outerVar = 'λ°–';
  
  function inner() {
    console.log(outerVar); // μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ 체인에 따라 μ ‘κ·Ό κ°€λŠ₯
  }

  inner();
}
outer();

 

μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” μ‹€ν–‰ μ‹œμ λ§ˆλ‹€ μŠ€νƒμ²˜λŸΌ μ»¨ν…μŠ€νŠΈλ₯Ό μŒ“μ•„κ°€λ©° μ‹€ν–‰ν•˜κ³ ,

이 μ»¨ν…μŠ€νŠΈλ₯Ό κΈ°μ€€μœΌλ‘œ λ³€μˆ˜λ‚˜ ν•¨μˆ˜μ— μ ‘κ·Όν•΄μš”. 이 ꡬ쑰λ₯Ό μ΄ν•΄ν•˜λ©΄ ν΄λ‘œμ €λ‚˜ this, 비동기 μ²˜λ¦¬λ„ 훨씬 μ΄ν•΄ν•˜κΈ° μ‰¬μ›Œμ Έμš”.


🎯 마무리 μš”μ•½

  • ν•¨μˆ˜λŠ” 선언식과 ν‘œν˜„μ‹μ΄ 있고, ν˜Έμ΄μŠ€νŒ… μ—¬λΆ€κ°€ λ‹€λ¦…λ‹ˆλ‹€.
  • 객체와 배열은 JSμ—μ„œ κ°€μž₯ 많이 μ‚¬μš©ν•˜λŠ” 자료 ꡬ쑰이며, λ©”μ„œλ“œμ™€ κ³ μ°¨ ν•¨μˆ˜μ— μ΅μˆ™ν•΄μ§ˆ ν•„μš”κ°€ μžˆμ–΄μš”.
  • DOM을 μ‘°μž‘ν•˜λ©΄ HTML μš”μ†Œλ₯Ό λ™μ μœΌλ‘œ λ°”κΏ€ 수 있고, 이벀트 μ²˜λ¦¬λ„ κ°€λŠ₯ν•©λ‹ˆλ‹€.
  • this, μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ, ν˜Έμ΄μŠ€νŒ… λ“± μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ μ‹€ν–‰ 흐름을 μ΄ν•΄ν•˜λŠ” 것은 μ‹€λ ₯을 ν•œ 단계 λŒμ–΄μ˜¬λ €μ€˜μš”.
λ°˜μ‘ν˜•