script.js

Download
javascript 616 lines 17.4 KB
  1/*
  2 * JavaScript ๊ธฐ์ดˆ ์˜ˆ์ œ
  3 * ๋ณ€์ˆ˜, ๋ฐ์ดํ„ฐ ํƒ€์ž…, ์—ฐ์‚ฐ์ž, ์กฐ๊ฑด๋ฌธ, ๋ฐ˜๋ณต๋ฌธ, ํ•จ์ˆ˜, ๋ฐฐ์—ด, ๊ฐ์ฒด, ํด๋ž˜์Šค
  4 */
  5
  6// ์ถœ๋ ฅ ํ•จ์ˆ˜
  7function log(message) {
  8    const output = document.getElementById('output');
  9    output.textContent += message + '\n';
 10    console.log(message);
 11}
 12
 13function clearOutput() {
 14    document.getElementById('output').textContent = '';
 15}
 16
 17// ============================================
 18// 1. ๋ณ€์ˆ˜
 19// ============================================
 20function runVariables() {
 21    clearOutput();
 22    log('=== ๋ณ€์ˆ˜ (var, let, const) ===\n');
 23
 24    // var - ํ•จ์ˆ˜ ์Šค์ฝ”ํ”„ (๋น„๊ถŒ์žฅ)
 25    var oldVar = "I'm var";
 26    log(`var oldVar = "${oldVar}"`);
 27
 28    // let - ๋ธ”๋ก ์Šค์ฝ”ํ”„, ์žฌํ• ๋‹น ๊ฐ€๋Šฅ
 29    let count = 0;
 30    log(`let count = ${count}`);
 31    count = 1;
 32    log(`count = ${count} (์žฌํ• ๋‹น ๊ฐ€๋Šฅ)`);
 33
 34    // const - ๋ธ”๋ก ์Šค์ฝ”ํ”„, ์žฌํ• ๋‹น ๋ถˆ๊ฐ€
 35    const PI = 3.14159;
 36    log(`\nconst PI = ${PI}`);
 37    // PI = 3; // Error!
 38
 39    const person = { name: "ํ™๊ธธ๋™" };
 40    log(`const person = { name: "${person.name}" }`);
 41    person.name = "๊น€์ฒ ์ˆ˜";
 42    log(`person.name = "${person.name}" (๊ฐ์ฒด ์†์„ฑ์€ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ)`);
 43
 44    // ์Šค์ฝ”ํ”„ ์ฐจ์ด
 45    log('\n--- ์Šค์ฝ”ํ”„ ์ฐจ์ด ---');
 46    if (true) {
 47        var varInBlock = "var๋Š” ๋ธ”๋ก ๋ฐ–์—์„œ๋„ ์ ‘๊ทผ ๊ฐ€๋Šฅ";
 48        let letInBlock = "let์€ ๋ธ”๋ก ๋‚ด์—์„œ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅ";
 49    }
 50    log(`๋ธ”๋ก ๋ฐ–์—์„œ var: ${varInBlock}`);
 51    // log(letInBlock); // Error: not defined
 52}
 53
 54// ============================================
 55// 2. ๋ฐ์ดํ„ฐ ํƒ€์ž…
 56// ============================================
 57function runDataTypes() {
 58    clearOutput();
 59    log('=== ๋ฐ์ดํ„ฐ ํƒ€์ž… ===\n');
 60
 61    // ๊ธฐ๋ณธ ํƒ€์ž…
 62    let str = "๋ฌธ์ž์—ด";
 63    let num = 42;
 64    let float = 3.14;
 65    let bool = true;
 66    let empty = null;
 67    let notDefined;
 68    let sym = Symbol("id");
 69    let big = 9007199254740991n;
 70
 71    log('--- ๊ธฐ๋ณธ ํƒ€์ž… (Primitive) ---');
 72    log(`String: "${str}" (typeof: ${typeof str})`);
 73    log(`Number (์ •์ˆ˜): ${num} (typeof: ${typeof num})`);
 74    log(`Number (์‹ค์ˆ˜): ${float} (typeof: ${typeof float})`);
 75    log(`Boolean: ${bool} (typeof: ${typeof bool})`);
 76    log(`Null: ${empty} (typeof: ${typeof empty})`); // ์ฃผ์˜: object๋กœ ๋‚˜์˜ด
 77    log(`Undefined: ${notDefined} (typeof: ${typeof notDefined})`);
 78    log(`Symbol: ${String(sym)} (typeof: ${typeof sym})`);
 79    log(`BigInt: ${big} (typeof: ${typeof big})`);
 80
 81    // ์ฐธ์กฐ ํƒ€์ž…
 82    log('\n--- ์ฐธ์กฐ ํƒ€์ž… (Reference) ---');
 83    let obj = { key: "value" };
 84    let arr = [1, 2, 3];
 85    let func = function() {};
 86
 87    log(`Object: ${JSON.stringify(obj)} (typeof: ${typeof obj})`);
 88    log(`Array: [${arr}] (typeof: ${typeof arr}, Array.isArray: ${Array.isArray(arr)})`);
 89    log(`Function: ${func.toString()} (typeof: ${typeof func})`);
 90
 91    // ํƒ€์ž… ๋ณ€ํ™˜
 92    log('\n--- ํƒ€์ž… ๋ณ€ํ™˜ ---');
 93    log(`String(123) = "${String(123)}"`);
 94    log(`Number("42") = ${Number("42")}`);
 95    log(`Boolean(0) = ${Boolean(0)}`);
 96    log(`Boolean("") = ${Boolean("")}`);
 97    log(`Boolean("hello") = ${Boolean("hello")}`);
 98    log(`parseInt("42px") = ${parseInt("42px")}`);
 99    log(`parseFloat("3.14abc") = ${parseFloat("3.14abc")}`);
100}
101
102// ============================================
103// 3. ์—ฐ์‚ฐ์ž
104// ============================================
105function runOperators() {
106    clearOutput();
107    log('=== ์—ฐ์‚ฐ์ž ===\n');
108
109    let a = 10, b = 3;
110
111    // ์‚ฐ์ˆ  ์—ฐ์‚ฐ์ž
112    log('--- ์‚ฐ์ˆ  ์—ฐ์‚ฐ์ž ---');
113    log(`${a} + ${b} = ${a + b}`);
114    log(`${a} - ${b} = ${a - b}`);
115    log(`${a} * ${b} = ${a * b}`);
116    log(`${a} / ${b} = ${a / b}`);
117    log(`${a} % ${b} = ${a % b} (๋‚˜๋จธ์ง€)`);
118    log(`${a} ** ${b} = ${a ** b} (๊ฑฐ๋“ญ์ œ๊ณฑ)`);
119
120    // ๋น„๊ต ์—ฐ์‚ฐ์ž
121    log('\n--- ๋น„๊ต ์—ฐ์‚ฐ์ž ---');
122    log(`5 == "5" : ${5 == "5"} (ํƒ€์ž… ๋ณ€ํ™˜ ํ›„ ๋น„๊ต)`);
123    log(`5 === "5" : ${5 === "5"} (ํƒ€์ž…๊นŒ์ง€ ๋น„๊ต)`);
124    log(`5 != "5" : ${5 != "5"}`);
125    log(`5 !== "5" : ${5 !== "5"}`);
126
127    // ๋…ผ๋ฆฌ ์—ฐ์‚ฐ์ž
128    log('\n--- ๋…ผ๋ฆฌ ์—ฐ์‚ฐ์ž ---');
129    log(`true && false = ${true && false}`);
130    log(`true || false = ${true || false}`);
131    log(`!true = ${!true}`);
132
133    // ์‚ผํ•ญ ์—ฐ์‚ฐ์ž
134    log('\n--- ์‚ผํ•ญ ์—ฐ์‚ฐ์ž ---');
135    let age = 20;
136    let status = age >= 18 ? "์„ฑ์ธ" : "๋ฏธ์„ฑ๋…„์ž";
137    log(`๋‚˜์ด: ${age}, ์ƒํƒœ: ${status}`);
138
139    // Nullish coalescing (??)
140    log('\n--- Nullish Coalescing (??) ---');
141    let value1 = null ?? "๊ธฐ๋ณธ๊ฐ’";
142    let value2 = 0 ?? "๊ธฐ๋ณธ๊ฐ’";
143    let value3 = "" ?? "๊ธฐ๋ณธ๊ฐ’";
144    log(`null ?? "๊ธฐ๋ณธ๊ฐ’" = "${value1}"`);
145    log(`0 ?? "๊ธฐ๋ณธ๊ฐ’" = ${value2} (0์€ null/undefined๊ฐ€ ์•„๋‹˜)`);
146    log(`"" ?? "๊ธฐ๋ณธ๊ฐ’" = "${value3}" (๋นˆ ๋ฌธ์ž์—ด๋„ ๊ฐ’)`);
147
148    // || vs ?? ์ฐจ์ด
149    log('\n--- || vs ?? ---');
150    log(`0 || "default" = "${0 || "default"}" (0์€ falsy)`);
151    log(`0 ?? "default" = ${0 ?? "default"} (0์€ null์ด ์•„๋‹˜)`);
152
153    // Optional chaining (?.)
154    log('\n--- Optional Chaining (?.) ---');
155    let user = { profile: { name: "ํ™๊ธธ๋™" } };
156    let emptyUser = {};
157    log(`user?.profile?.name = "${user?.profile?.name}"`);
158    log(`emptyUser?.profile?.name = ${emptyUser?.profile?.name}`);
159}
160
161// ============================================
162// 4. ์กฐ๊ฑด๋ฌธ
163// ============================================
164function runConditions() {
165    clearOutput();
166    log('=== ์กฐ๊ฑด๋ฌธ ===\n');
167
168    // if-else
169    log('--- if-else ---');
170    let score = 85;
171    let grade;
172
173    if (score >= 90) {
174        grade = 'A';
175    } else if (score >= 80) {
176        grade = 'B';
177    } else if (score >= 70) {
178        grade = 'C';
179    } else {
180        grade = 'F';
181    }
182    log(`์ ์ˆ˜: ${score}, ํ•™์ : ${grade}`);
183
184    // switch
185    log('\n--- switch ---');
186    let day = new Date().getDay();
187    let dayName;
188
189    switch (day) {
190        case 0:
191            dayName = "์ผ์š”์ผ";
192            break;
193        case 1:
194            dayName = "์›”์š”์ผ";
195            break;
196        case 2:
197            dayName = "ํ™”์š”์ผ";
198            break;
199        case 3:
200            dayName = "์ˆ˜์š”์ผ";
201            break;
202        case 4:
203            dayName = "๋ชฉ์š”์ผ";
204            break;
205        case 5:
206            dayName = "๊ธˆ์š”์ผ";
207            break;
208        case 6:
209            dayName = "ํ† ์š”์ผ";
210            break;
211        default:
212            dayName = "์•Œ ์ˆ˜ ์—†์Œ";
213    }
214    log(`์˜ค๋Š˜์€ ${dayName}์ž…๋‹ˆ๋‹ค.`);
215
216    // Truthy์™€ Falsy
217    log('\n--- Truthy์™€ Falsy ---');
218    const falsyValues = [false, 0, -0, 0n, "", null, undefined, NaN];
219    log('Falsy ๊ฐ’๋“ค:');
220    falsyValues.forEach(v => {
221        log(`  ${String(v)} (${typeof v}) => ${Boolean(v) ? 'truthy' : 'falsy'}`);
222    });
223
224    log('\n๋ชจ๋“  ๋‹ค๋ฅธ ๊ฐ’์€ truthy์ž…๋‹ˆ๋‹ค:');
225    log(`  "0" => ${Boolean("0") ? 'truthy' : 'falsy'}`);
226    log(`  [] => ${Boolean([]) ? 'truthy' : 'falsy'}`);
227    log(`  {} => ${Boolean({}) ? 'truthy' : 'falsy'}`);
228}
229
230// ============================================
231// 5. ๋ฐ˜๋ณต๋ฌธ
232// ============================================
233function runLoops() {
234    clearOutput();
235    log('=== ๋ฐ˜๋ณต๋ฌธ ===\n');
236
237    // for
238    log('--- for ๋ฌธ ---');
239    let sum = 0;
240    for (let i = 1; i <= 5; i++) {
241        sum += i;
242    }
243    log(`1๋ถ€ํ„ฐ 5๊นŒ์ง€์˜ ํ•ฉ: ${sum}`);
244
245    // while
246    log('\n--- while ๋ฌธ ---');
247    let count = 0;
248    while (count < 3) {
249        log(`count: ${count}`);
250        count++;
251    }
252
253    // for...of (๋ฐฐ์—ด ์ˆœํšŒ)
254    log('\n--- for...of (๋ฐฐ์—ด ์ˆœํšŒ) ---');
255    const fruits = ["์‚ฌ๊ณผ", "๋ฐ”๋‚˜๋‚˜", "์˜ค๋ Œ์ง€"];
256    for (const fruit of fruits) {
257        log(`๊ณผ์ผ: ${fruit}`);
258    }
259
260    // for...in (๊ฐ์ฒด ํ‚ค ์ˆœํšŒ)
261    log('\n--- for...in (๊ฐ์ฒด ํ‚ค ์ˆœํšŒ) ---');
262    const person = { name: "ํ™๊ธธ๋™", age: 25, city: "์„œ์šธ" };
263    for (const key in person) {
264        log(`${key}: ${person[key]}`);
265    }
266
267    // forEach
268    log('\n--- forEach ---');
269    fruits.forEach((fruit, index) => {
270        log(`[${index}] ${fruit}`);
271    });
272
273    // break์™€ continue
274    log('\n--- break์™€ continue ---');
275    log('continue๋กœ 3 ๊ฑด๋„ˆ๋›ฐ๊ธฐ:');
276    for (let i = 1; i <= 5; i++) {
277        if (i === 3) continue;
278        log(`  i = ${i}`);
279    }
280
281    log('break๋กœ 3์—์„œ ์ค‘๋‹จ:');
282    for (let i = 1; i <= 5; i++) {
283        if (i === 3) break;
284        log(`  i = ${i}`);
285    }
286}
287
288// ============================================
289// 6. ํ•จ์ˆ˜
290// ============================================
291function runFunctions() {
292    clearOutput();
293    log('=== ํ•จ์ˆ˜ ===\n');
294
295    // ํ•จ์ˆ˜ ์„ ์–ธ์‹
296    log('--- ํ•จ์ˆ˜ ์„ ์–ธ์‹ ---');
297    function greet1(name) {
298        return `Hello, ${name}!`;
299    }
300    log(greet1("ํ™๊ธธ๋™"));
301
302    // ํ•จ์ˆ˜ ํ‘œํ˜„์‹
303    log('\n--- ํ•จ์ˆ˜ ํ‘œํ˜„์‹ ---');
304    const greet2 = function(name) {
305        return `Hi, ${name}!`;
306    };
307    log(greet2("๊น€์ฒ ์ˆ˜"));
308
309    // ํ™”์‚ดํ‘œ ํ•จ์ˆ˜
310    log('\n--- ํ™”์‚ดํ‘œ ํ•จ์ˆ˜ ---');
311    const greet3 = (name) => `Hey, ${name}!`;
312    log(greet3("์ด์˜ํฌ"));
313
314    // ๊ธฐ๋ณธ ๋งค๊ฐœ๋ณ€์ˆ˜
315    log('\n--- ๊ธฐ๋ณธ ๋งค๊ฐœ๋ณ€์ˆ˜ ---');
316    const greet4 = (name = "Guest") => `Welcome, ${name}!`;
317    log(greet4());
318    log(greet4("๋ฐ•์ง€๋ฏผ"));
319
320    // Rest ํŒŒ๋ผ๋ฏธํ„ฐ
321    log('\n--- Rest ํŒŒ๋ผ๋ฏธํ„ฐ ---');
322    const sumAll = (...numbers) => {
323        return numbers.reduce((acc, num) => acc + num, 0);
324    };
325    log(`sumAll(1, 2, 3, 4, 5) = ${sumAll(1, 2, 3, 4, 5)}`);
326
327    // ๊ตฌ์กฐ ๋ถ„ํ•ด ๋งค๊ฐœ๋ณ€์ˆ˜
328    log('\n--- ๊ตฌ์กฐ ๋ถ„ํ•ด ๋งค๊ฐœ๋ณ€์ˆ˜ ---');
329    const printPerson = ({ name, age }) => {
330        return `${name}๋‹˜์€ ${age}์„ธ์ž…๋‹ˆ๋‹ค.`;
331    };
332    log(printPerson({ name: "ํ™๊ธธ๋™", age: 25 }));
333
334    // ์ฆ‰์‹œ ์‹คํ–‰ ํ•จ์ˆ˜ (IIFE)
335    log('\n--- ์ฆ‰์‹œ ์‹คํ–‰ ํ•จ์ˆ˜ (IIFE) ---');
336    const result = (function(x, y) {
337        return x + y;
338    })(3, 4);
339    log(`IIFE ๊ฒฐ๊ณผ: ${result}`);
340
341    // ํด๋กœ์ €
342    log('\n--- ํด๋กœ์ € ---');
343    function createCounter() {
344        let count = 0;
345        return {
346            increment: () => ++count,
347            decrement: () => --count,
348            getCount: () => count
349        };
350    }
351    const counter = createCounter();
352    log(`count: ${counter.getCount()}`);
353    log(`increment: ${counter.increment()}`);
354    log(`increment: ${counter.increment()}`);
355    log(`decrement: ${counter.decrement()}`);
356}
357
358// ============================================
359// 7. ๋ฐฐ์—ด
360// ============================================
361function runArrays() {
362    clearOutput();
363    log('=== ๋ฐฐ์—ด ===\n');
364
365    // ๋ฐฐ์—ด ์ƒ์„ฑ
366    log('--- ๋ฐฐ์—ด ์ƒ์„ฑ ---');
367    const arr1 = [1, 2, 3];
368    const arr2 = new Array(3).fill(0);
369    const arr3 = Array.from({ length: 5 }, (_, i) => i + 1);
370    log(`๋ฆฌํ„ฐ๋Ÿด: [${arr1}]`);
371    log(`fill: [${arr2}]`);
372    log(`Array.from: [${arr3}]`);
373
374    // ๊ธฐ๋ณธ ๋ฉ”์„œ๋“œ
375    log('\n--- ๊ธฐ๋ณธ ๋ฉ”์„œ๋“œ ---');
376    const fruits = ["์‚ฌ๊ณผ", "๋ฐ”๋‚˜๋‚˜"];
377    log(`์›๋ณธ: [${fruits}]`);
378
379    fruits.push("์˜ค๋ Œ์ง€");
380    log(`push("์˜ค๋ Œ์ง€"): [${fruits}]`);
381
382    fruits.pop();
383    log(`pop(): [${fruits}]`);
384
385    fruits.unshift("๋”ธ๊ธฐ");
386    log(`unshift("๋”ธ๊ธฐ"): [${fruits}]`);
387
388    fruits.shift();
389    log(`shift(): [${fruits}]`);
390
391    // ๋ฐฐ์—ด ์กฐ์ž‘
392    log('\n--- ๋ฐฐ์—ด ์กฐ์ž‘ ---');
393    const numbers = [1, 2, 3, 4, 5];
394    log(`์›๋ณธ: [${numbers}]`);
395    log(`slice(1, 3): [${numbers.slice(1, 3)}]`);
396    log(`concat([6, 7]): [${numbers.concat([6, 7])}]`);
397    log(`indexOf(3): ${numbers.indexOf(3)}`);
398    log(`includes(3): ${numbers.includes(3)}`);
399    log(`join("-"): "${numbers.join("-")}"`);
400    log(`reverse(): [${[...numbers].reverse()}]`);
401
402    // ๊ณ ์ฐจ ํ•จ์ˆ˜
403    log('\n--- ๊ณ ์ฐจ ํ•จ์ˆ˜ ---');
404    const nums = [1, 2, 3, 4, 5];
405    log(`์›๋ณธ: [${nums}]`);
406    log(`map(n => n * 2): [${nums.map(n => n * 2)}]`);
407    log(`filter(n => n > 2): [${nums.filter(n => n > 2)}]`);
408    log(`find(n => n > 2): ${nums.find(n => n > 2)}`);
409    log(`findIndex(n => n > 2): ${nums.findIndex(n => n > 2)}`);
410    log(`reduce((acc, n) => acc + n, 0): ${nums.reduce((acc, n) => acc + n, 0)}`);
411    log(`every(n => n > 0): ${nums.every(n => n > 0)}`);
412    log(`some(n => n > 4): ${nums.some(n => n > 4)}`);
413    log(`sort((a, b) => b - a): [${[...nums].sort((a, b) => b - a)}]`);
414
415    // ์Šคํ”„๋ ˆ๋“œ ์—ฐ์‚ฐ์ž
416    log('\n--- ์Šคํ”„๋ ˆ๋“œ ์—ฐ์‚ฐ์ž ---');
417    const arr = [1, 2, 3];
418    const newArr = [...arr, 4, 5];
419    log(`[...arr, 4, 5]: [${newArr}]`);
420    log(`Math.max(...arr): ${Math.max(...arr)}`);
421
422    // ๊ตฌ์กฐ ๋ถ„ํ•ด
423    log('\n--- ๊ตฌ์กฐ ๋ถ„ํ•ด ---');
424    const [first, second, ...rest] = [1, 2, 3, 4, 5];
425    log(`[first, second, ...rest] = [1, 2, 3, 4, 5]`);
426    log(`first: ${first}, second: ${second}, rest: [${rest}]`);
427}
428
429// ============================================
430// 8. ๊ฐ์ฒด
431// ============================================
432function runObjects() {
433    clearOutput();
434    log('=== ๊ฐ์ฒด ===\n');
435
436    // ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด
437    log('--- ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด ---');
438    const person = {
439        name: "ํ™๊ธธ๋™",
440        age: 25,
441        city: "์„œ์šธ",
442        greet() {
443            return `์•ˆ๋…•ํ•˜์„ธ์š”, ${this.name}์ž…๋‹ˆ๋‹ค.`;
444        }
445    };
446    log(`person: ${JSON.stringify(person, null, 2)}`);
447    log(`person.greet(): ${person.greet()}`);
448
449    // ์†์„ฑ ์ ‘๊ทผ
450    log('\n--- ์†์„ฑ ์ ‘๊ทผ ---');
451    log(`person.name: "${person.name}"`);
452    log(`person["age"]: ${person["age"]}`);
453
454    const key = "city";
455    log(`person[key] (key="city"): "${person[key]}"`);
456
457    // ์†์„ฑ ์ถ”๊ฐ€/์ˆ˜์ •/์‚ญ์ œ
458    log('\n--- ์†์„ฑ ์ถ”๊ฐ€/์ˆ˜์ •/์‚ญ์ œ ---');
459    person.email = "hong@example.com";
460    log(`์ถ”๊ฐ€: person.email = "${person.email}"`);
461
462    person.age = 26;
463    log(`์ˆ˜์ •: person.age = ${person.age}`);
464
465    delete person.city;
466    log(`์‚ญ์ œ ํ›„ keys: [${Object.keys(person)}]`);
467
468    // ๊ตฌ์กฐ ๋ถ„ํ•ด ํ• ๋‹น
469    log('\n--- ๊ตฌ์กฐ ๋ถ„ํ•ด ํ• ๋‹น ---');
470    const { name, age, email = "์—†์Œ" } = person;
471    log(`const { name, age, email = "์—†์Œ" } = person`);
472    log(`name: "${name}", age: ${age}, email: "${email}"`);
473
474    // ๋ณ„์นญ
475    const { name: userName } = person;
476    log(`const { name: userName } = person => userName: "${userName}"`);
477
478    // ์Šคํ”„๋ ˆ๋“œ ์—ฐ์‚ฐ์ž
479    log('\n--- ์Šคํ”„๋ ˆ๋“œ ์—ฐ์‚ฐ์ž ---');
480    const newPerson = { ...person, city: "๋ถ€์‚ฐ", country: "ํ•œ๊ตญ" };
481    log(`{ ...person, city: "๋ถ€์‚ฐ" }:`);
482    log(JSON.stringify(newPerson, null, 2));
483
484    // Object ๋ฉ”์„œ๋“œ
485    log('\n--- Object ๋ฉ”์„œ๋“œ ---');
486    const obj = { a: 1, b: 2, c: 3 };
487    log(`Object.keys(obj): [${Object.keys(obj)}]`);
488    log(`Object.values(obj): [${Object.values(obj)}]`);
489    log(`Object.entries(obj): ${JSON.stringify(Object.entries(obj))}`);
490
491    // Object.assign
492    const merged = Object.assign({}, obj, { d: 4 });
493    log(`Object.assign({}, obj, { d: 4 }): ${JSON.stringify(merged)}`);
494
495    // ์†์„ฑ ์กด์žฌ ํ™•์ธ
496    log('\n--- ์†์„ฑ ์กด์žฌ ํ™•์ธ ---');
497    log(`"a" in obj: ${"a" in obj}`);
498    log(`obj.hasOwnProperty("a"): ${obj.hasOwnProperty("a")}`);
499}
500
501// ============================================
502// 9. ํด๋ž˜์Šค
503// ============================================
504function runClasses() {
505    clearOutput();
506    log('=== ํด๋ž˜์Šค (ES6) ===\n');
507
508    // ๊ธฐ๋ณธ ํด๋ž˜์Šค
509    log('--- ๊ธฐ๋ณธ ํด๋ž˜์Šค ---');
510    class Animal {
511        constructor(name) {
512            this.name = name;
513        }
514
515        speak() {
516            return `${this.name} makes a sound.`;
517        }
518    }
519
520    const animal = new Animal("๋™๋ฌผ");
521    log(`new Animal("๋™๋ฌผ")`);
522    log(`animal.speak(): "${animal.speak()}"`);
523
524    // ์ƒ์†
525    log('\n--- ์ƒ์† ---');
526    class Dog extends Animal {
527        constructor(name, breed) {
528            super(name);
529            this.breed = breed;
530        }
531
532        speak() {
533            return `${this.name}(${this.breed})๊ฐ€ ๋ฉ๋ฉ ์ง–์Šต๋‹ˆ๋‹ค!`;
534        }
535
536        fetch() {
537            return `${this.name}๊ฐ€ ๊ณต์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.`;
538        }
539    }
540
541    const dog = new Dog("๋ฉ๋ฉ์ด", "์ง„๋—๊ฐœ");
542    log(`new Dog("๋ฉ๋ฉ์ด", "์ง„๋—๊ฐœ")`);
543    log(`dog.speak(): "${dog.speak()}"`);
544    log(`dog.fetch(): "${dog.fetch()}"`);
545
546    // Getter์™€ Setter
547    log('\n--- Getter์™€ Setter ---');
548    class Circle {
549        constructor(radius) {
550            this._radius = radius;
551        }
552
553        get radius() {
554            return this._radius;
555        }
556
557        set radius(value) {
558            if (value > 0) {
559                this._radius = value;
560            }
561        }
562
563        get area() {
564            return Math.PI * this._radius ** 2;
565        }
566    }
567
568    const circle = new Circle(5);
569    log(`circle.radius: ${circle.radius}`);
570    log(`circle.area: ${circle.area.toFixed(2)}`);
571    circle.radius = 10;
572    log(`circle.radius = 10 ํ›„ area: ${circle.area.toFixed(2)}`);
573
574    // Static ๋ฉ”์„œ๋“œ
575    log('\n--- Static ๋ฉ”์„œ๋“œ ---');
576    class MathUtil {
577        static PI = 3.14159;
578
579        static add(a, b) {
580            return a + b;
581        }
582
583        static multiply(a, b) {
584            return a * b;
585        }
586    }
587
588    log(`MathUtil.PI: ${MathUtil.PI}`);
589    log(`MathUtil.add(3, 4): ${MathUtil.add(3, 4)}`);
590    log(`MathUtil.multiply(3, 4): ${MathUtil.multiply(3, 4)}`);
591
592    // Private ํ•„๋“œ (# ๋ฌธ๋ฒ•, ES2022)
593    log('\n--- Private ํ•„๋“œ ---');
594    class BankAccount {
595        #balance = 0;
596
597        deposit(amount) {
598            this.#balance += amount;
599            return this.#balance;
600        }
601
602        getBalance() {
603            return this.#balance;
604        }
605    }
606
607    const account = new BankAccount();
608    log(`account.deposit(1000): ${account.deposit(1000)}`);
609    log(`account.deposit(500): ${account.deposit(500)}`);
610    log(`account.getBalance(): ${account.getBalance()}`);
611    // log(account.#balance); // Error: Private field
612}
613
614// ํŽ˜์ด์ง€ ๋กœ๋“œ ์‹œ ์•ˆ๋‚ด ๋ฉ”์‹œ์ง€
615log('๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜์—ฌ ๊ฐ ์„น์…˜์˜ ์˜ˆ์ œ๋ฅผ ์‹คํ–‰ํ•˜์„ธ์š”.');