** π κ°μ²΄ μμ± λ°©μ μμ ν΄λΆ**
μμ± λ°©λ² | λ¬Έλ² | νΉμ§ | μ£Όμμ¬ν |
---|---|---|---|
κ°μ²΄ 리ν°λ΄ | { key: value } |
κ°μ₯ κ°λ¨, μ¦μμμ κ°μ²΄ μμ± | λ©μλ 곡μ λΆκ° (λ©λͺ¨λ¦¬ λΉν¨μ¨) |
μμ±μ ν¨μ | function Person() {} |
λμΌν ꡬ쑰 κ°μ²΄ μμ± κ°λ₯, νλ‘ν νμ μ¬μ© | new μ μ°λ©΄ undefined λ°ν |
Object.create() | Object.create(proto) |
μνλ νλ‘ν νμ μ§μ μ§μ | νλ‘νΌν° μΆκ° λ³λ νμ |
ES6 ν΄λμ€ | class Person {} |
λ¬Έλ²μ μ€ν, λ΄λΆλ μ¬μ ν νλ‘ν νμ | μ€μ λμμ ES5 λ°©μκ³Ό λμΌ |
π μμ λΉκ΅
// 1. κ°μ²΄ 리ν°λ΄
const obj = { name: 'JS' };
// 2. μμ±μ ν¨μ
function Person(name) {
this.name = name;
}
const p1 = new Person('Tom');
// 3. Object.create()
const proto = { greet() { console.log('Hello'); } };
const obj2 = Object.create(proto);
obj2.greet();
// 4. ν΄λμ€
class Animal {
constructor(type) {
this.type = type;
}
speak() {
console.log(`${this.type} sound`);
}
}
const dog = new Animal('Dog');
dog.speak();
π§ μ μμ±μ ν¨μ & ν΄λμ€κ° νλ‘ν νμ μ μ°λ?
- κ°μ²΄ 리ν°λ΄ β λ§€ κ°μ²΄λ§λ€ λ©μλ μλ‘ μμ± β λ©λͺ¨λ¦¬ λΉν¨μ¨
- μμ±μ/ν΄λμ€ β κ³΅ν΅ λ©μλλ₯Ό νλ‘ν νμ μ λ£μ΄ 곡μ β ν¨μ¨μ
π₯ 2οΈβ£ νλ‘ν νμ & νλ‘ν νμ μ²΄μΈ μ¬ν
π ν΅μ¬ μ©μ΄ λͺ νν ꡬλΆ
μ©μ΄ | μμΉ | μ€λͺ |
---|---|---|
prototype |
ν¨μ(μμ±μ ν¨μ or ν΄λμ€) | ν΄λΉ ν¨μλ‘ μμ±λ κ°μ²΄κ° μ°Έμ‘°νλ νλ‘ν νμ κ°μ²΄ |
__proto__ |
λͺ¨λ κ°μ²΄ | μ€μ λΆλͺ¨ κ°μ²΄μ prototype μ μ°Έμ‘° |
π― νλ‘ν νμ μ²΄μΈ μκ°ν
κ°μ²΄ β __proto__ β μμ±μ ν¨μμ prototype β Object.prototype β null
π μμ : νμΈ
javascript
볡μ¬νΈμ§
function Person(name) { this.name = name; }
Person.prototype.sayHi = function() { console.log(`Hi ${this.name}`); };
const p1 = new Person('Tom');
console.log(p1.__proto__ === Person.prototype); // true
console.log(Person.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__); // null
π 3οΈβ£ νλ‘ν νμ μ²΄μΈ νμ νλ¦
- κ°μ²΄ μμ μμ νλ‘νΌν°/λ©μλ μ°ΎκΈ°
- μμΌλ©΄ β
__proto__
β λΆλͺ¨ νλ‘ν νμ μΌλ‘ μ΄λ - Object.prototypeκΉμ§ μ¬λΌκ°λ μμΌλ©΄ β undefined
ποΈ 4οΈβ£ ES5 vs ES6 μμ μλ²½ λΉκ΅
π ES5: νλ‘ν νμ κΈ°λ° μμ
function Animal(type) {
this.type = type;
}
Animal.prototype.speak = function() {
console.log(`${this.type} sound`);
};
function Dog(name) {
Animal.call(this, 'Dog'); // super
this.name = name;
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
const d1 = new Dog('Max');
d1.speak(); // Dog sound
π¦ ES6: class κΈ°λ° μμ
class Animal {
constructor(type) {
this.type = type;
}
speak() {
console.log(`${this.type} sound`);
}
}
class Dog extends Animal {
constructor(name) {
super('Dog');
this.name = name;
}
}
const d2 = new Dog('Buddy');
d2.speak(); // Dog sound
β λ΄λΆμ μΌλ‘ μ¬μ ν νλ‘ν νμ κΈ°λ°
π§ 5οΈβ£ κΈ°μ λ©΄μ ν¬μΈνΈ μ 리
μ§λ¬Έ | λ΅λ³ ν¬μΈνΈ |
---|---|
__proto__ μ prototype μ°¨μ΄? |
__proto__ : κ°μ²΄μ λ΄λΆ μ°Έμ‘°, prototype : ν¨μμλ§ μ‘΄μ¬ |
νλ‘ν νμ μ²΄μΈ λμ? | κ°μ²΄ β λΆλͺ¨ νλ‘ν νμ
β μ΅μ’
Object.prototype |
ES5 vs ES6 μμ μ°¨μ΄? | ES5: μμμ νλ‘ν νμ μ°κ²°, ES6: λ¬Έλ²μ μ€ν |
ν΄λμ€κ° νλ‘ν νμ κΈ°λ°μΈ μ΄μ ? | λ©μλ 곡μ μ΅μ ν, κΈ°μ‘΄ JS μμ§ νΈνμ± |
λ©μλ λ©λͺ¨λ¦¬ ν¨μ¨μ±? | νλ‘ν νμ μ μ μ₯ β λͺ¨λ μΈμ€ν΄μ€κ° 곡μ |
π 6οΈβ£ λ Έμ μ© μμ½ μ 리
π κ°μ²΄ μμ± λ°©λ² μ 리
λ°©μ | λ¬Έλ² | νΉμ§ | μ£Όμ |
---|---|---|---|
κ°μ²΄ 리ν°λ΄ | {} |
μ§κ΄μ | λ©μλ 곡μ λΆκ° |
μμ±μ ν¨μ | function(){} |
μ¬μ¬μ©μ±, νλ‘ν νμ λͺ μ | new μ μ°λ©΄ undefined |
Object.create() | Object.create(proto) |
μνλ νλ‘ν νμ μ€μ | νλ‘νΌν° μΆκ° νμ |
ν΄λμ€ | class |
κ°λ μ±, μμ κΉλ | λ΄λΆλ νλ‘ν νμ |
π νλ‘ν νμ ν΅μ¬
μ©μ΄ | μ€λͺ |
---|---|
prototype |
ν¨μμ μ‘΄μ¬, κ°μ²΄ μμ± μ μ°Έμ‘° |
__proto__ |
κ°μ²΄μ μ‘΄μ¬, λΆλͺ¨ νλ‘ν νμ μ°κ²° |
νλ‘ν νμ μ²΄μΈ | κ°μ²΄ β λΆλͺ¨ β Object.prototype |
π₯ 7οΈβ£ μ€λ¬΄ & λ©΄μ μ¬ν νμ₯ κ°λ₯:
- νλ‘ν νμ μ²΄μΈ λμν μλ£
- Prototype Pollution 보μ μ΄μ
- 컀μ€ν Object.create ν¨ν΄ & λͺ¨λν ν¨ν΄
- ν΄λμ€ private νλ & Symbol νμ©
- λ©΄μ λλΉ - νλ‘ν νμ κ³Ό ν΄λμ€ μ¬μΈ΅ μ§λ¬Έ μΈνΈ
νμνμλ©΄ λ°λ‘ μκ° μλ£, μ€μ λ¬Έμ μΈνΈ, λ§ν¬λ€μ΄μΌλ‘ μ 곡 κ°λ₯ν΄μ! μΆκ°λ‘ μ¬ν μμ² μ£Όμλ©΄ λ°λ‘ μ€λΉν κ²μ! ππ₯
π¦ κ°μ²΄ 1
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JavaScript κ°μ²΄ μ¬ν μμ </title>
<style>
.area {
background: lightgray;
border: 1px solid black;
width: 500px;
margin-bottom: 10px;
padding: 10px;
white-space: pre-wrap; /* μ€λ°κΏ μ μ§ */
}
.big { height: 500px; overflow-y: scroll; }
</style>
</head>
<body>
<h2>π’ JavaScript κ°μ²΄(Object) μ¬ν μμ </h2>
<div class="area big" id="outputArea"> <!-- κ²°κ³Ό μΆλ ₯ μμ --></div>
<script>
function objectExamples() {
const output = document.getElementById("outputArea");
/* ---------------------------------------------------
β
1. κ°μ²΄ μ μΈ κΈ°λ³Έ - κΈ°μ΄
--------------------------------------------------- */
const product = {
name: "λ§κ³ νΌν΄", // π₯ μν μ΄λ¦
price: 4000, // π° κ°κ²©
ingredients: ["λ§κ³ ", "μ€ν", "μμ΄"], // π§ μ¬λ£ (λ°°μ΄)
isAvailable: true // β
νλ§€ μ¬λΆ
};
output.innerHTML += "π¦ κΈ°λ³Έ κ°μ²΄ μ μΈ:\n";
output.innerHTML += JSON.stringify(product) + "\n\n";
/* ---------------------------------------------------
β
2. κ°μ²΄ μμ± μ κ·Ό - μ νκΈ°λ² & λκ΄νΈ νκΈ°λ²
--------------------------------------------------- */
output.innerHTML += "π μ νκΈ°λ²μΌλ‘ μ κ·Ό: " + product.name + "\n";
output.innerHTML += "π λκ΄νΈ νκΈ°λ²μΌλ‘ μ κ·Ό: " + product['price'] + "μ\n\n";
/* ---------------------------------------------------
β
3. μμ± μΆκ°, μμ , μμ
--------------------------------------------------- */
product.origin = "ν리ν"; // β μμ± μΆκ°
product.price = 4500; // βοΈ μμ± μμ
delete product.isAvailable; // β μμ± μμ
output.innerHTML += "π οΈ μμ± μΆκ°/μμ /μμ ν:\n" + JSON.stringify(product) + "\n\n";
/* ---------------------------------------------------
β
4. κ³μ°λ μμ±λͺ
(λμ key)
--------------------------------------------------- */
const keyName = "special-offer";
const dynamicProduct = {
[keyName]: "μΈμΌ μ€", // π λκ΄νΈ μμ λ³μ μ¬μ©
price: 3000
};
output.innerHTML += "βοΈ κ³μ°λ μμ±λͺ
μ¬μ©:\n" + JSON.stringify(dynamicProduct) + "\n\n";
/* ---------------------------------------------------
β
5. κ°μ²΄ λ©μλ μ μΈκ³Ό this μ¬μ©
--------------------------------------------------- */
const person = {
firstName: "ν",
lastName: "κΈΈλ",
fullName: function() {
return `${this.firstName} ${this.lastName}`; // thisλ‘ μκΈ° μμ μ°Έμ‘°
}
};
output.innerHTML += "π€ λ©μλ μ¬μ©: " + person.fullName() + "\n\n";
/* ---------------------------------------------------
β
6. for...in λ¬ΈμΌλ‘ κ°μ²΄ λ°λ³΅
--------------------------------------------------- */
output.innerHTML += "π for...in λ°λ³΅:\n";
for (let key in product) {
output.innerHTML += `β‘οΈ ${key}: ${product[key]}\n`;
}
output.innerHTML += "\n";
/* ---------------------------------------------------
β
7. Object.keys, values, entries
--------------------------------------------------- */
output.innerHTML += "ποΈ Object.keys: " + JSON.stringify(Object.keys(product)) + "\n";
output.innerHTML += "π’ Object.values: " + JSON.stringify(Object.values(product)) + "\n";
output.innerHTML += "π Object.entries:\n";
Object.entries(product).forEach(([key, value]) => {
output.innerHTML += `β‘οΈ ${key}: ${value}\n`;
});
output.innerHTML += "\n";
/* ---------------------------------------------------
β
8. κ°μ²΄ λ³΅μ¬ - μμ 볡μ¬
--------------------------------------------------- */
const copy1 = Object.assign({}, product);
const copy2 = { ...product }; // μ€νλ λ μ°μ°μ
output.innerHTML += "π μμ 볡μ¬(Object.assign): " + JSON.stringify(copy1) + "\n";
output.innerHTML += "π μμ 볡μ¬(μ€νλ λ): " + JSON.stringify(copy2) + "\n\n";
/* ---------------------------------------------------
β
9. μ€μ²© κ°μ²΄μ λ©μλμμμ this
--------------------------------------------------- */
const order = {
orderId: 101,
customer: {
name: "νκΈΈλ",
address: "μμΈ"
},
total: 5000,
summary() {
return `μ£Όλ¬Έλ²νΈ: ${this.orderId}, κ³ κ°: ${this.customer.name}, μ΄μ‘: ${this.total}μ`;
}
};
output.innerHTML += "π μ€μ²© κ°μ²΄ + λ©μλ μ¬μ©:\n" + order.summary() + "\n\n";
/* ---------------------------------------------------
β
10. κ°μ²΄ λΉκ΅¬μ‘°ν ν λΉ (Destructuring)
--------------------------------------------------- */
const { name, price } = product;
output.innerHTML += `π¦ λΉκ΅¬μ‘°ν ν λΉ: μνλͺ
= ${name}, κ°κ²© = ${price}μ\n\n`;
/* ---------------------------------------------------
β
11. κ°μ²΄ κΉμ λ³΅μ¬ (deep copy)
--------------------------------------------------- */
const deepCopy = JSON.parse(JSON.stringify(order));
deepCopy.customer.name = "μκΊ½μ "; // μλ³Έ μν₯ X
output.innerHTML += "π κΉμ λ³΅μ¬ ν μμ :\n";
output.innerHTML += `μλ³Έ κ³ κ°λͺ
: ${order.customer.name}, λ³΅μ¬ κ³ κ°λͺ
: ${deepCopy.customer.name}\n\n`;
/* ---------------------------------------------------
β
12. κ°μ²΄ λΉκ΅ νΉμ§
--------------------------------------------------- */
const objA = { a: 1 };
const objB = { a: 1 };
output.innerHTML += `β οΈ κ°μ²΄ λΉκ΅: objA === objB β ${objA === objB}\n`; // false (μ£Όμ λ€λ¦)
const objC = objA;
output.innerHTML += `β
λμΌ μ°Έμ‘° λΉκ΅: objA === objC β ${objA === objC}\n`; // true
}
// ν¨μ μ€ν
objectExamples();
</script>
</body>
</html>
π¦ κ°μ²΄ 2
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>JavaScript Object Deep Dive</title>
</head>
<body>
<script>
/************************************************
* π’ [1] κ°μ²΄ 리ν°λ΄ λ°©μ (κ°μ₯ κΈ°λ³Έ)
************************************************/
const product1 = {
code: 'A1000',
name: 'μλ£μ',
price: 1000,
showInfo: function() {
console.log(`π¦ [리ν°λ΄] μνλͺ
: ${this.name}, π° κ°κ²©: ${this.price}μ`);
}
};
product1.showInfo();
/************************************************
* π’ [2] μμ±μ ν¨μ λ°©μ (κΈ°μ΄)
************************************************/
function Product(code, name, price) {
this.code = code;
this.name = name;
this.price = price;
// λΉν¨μ¨μ λ©μλ (κ° κ°μ²΄λ§λ€ 볡μ¬λ¨)
this.showInfo = function() {
console.log(`π¦ [μμ±μ ν¨μ] μνλͺ
: ${this.name}, π° κ°κ²©: ${this.price}μ`);
};
}
let p1 = new Product('A1001', 'μΉν μ€', 2000);
let p2 = new Product('A1002', 'μ΄μ½λ¦Ώ', 1500);
p1.showInfo();
p2.showInfo();
/************************************************
* π’ [3] νλ‘ν νμ
μΌλ‘ λ©μλ 곡μ (μΆμ²!)
************************************************/
function ProductProto(code, name, price) {
this.code = code;
this.name = name;
this.price = price;
}
// β
λ©μλλ₯Ό νλ‘ν νμ
μ μΆκ° β λͺ¨λ κ°μ²΄κ° 곡μ !
ProductProto.prototype.showInfo = function() {
console.log(`π¦ [νλ‘ν νμ
] μνλͺ
: ${this.name}, π° κ°κ²©: ${this.price}μ`);
};
let p3 = new ProductProto('A1003', 'μΏ ν€', 1800);
let p4 = new ProductProto('A1004', 'μ¬ν', 1000);
p3.showInfo();
p4.showInfo();
/************************************************
* π’ [4] ES6 ν΄λμ€ λ¬Έλ² (κ°λ
μ± μ’μ, μΆμ²!)
************************************************/
class ProductClass {
constructor(code, name, price) {
this.code = code;
this.name = name;
this.price = price;
}
showInfo() {
console.log(`π¦ [ν΄λμ€] μνλͺ
: ${this.name}, π° κ°κ²©: ${this.price}μ`);
}
}
let p5 = new ProductClass('A1005', 'λΌλ©΄', 1200);
p5.showInfo();
/************************************************
* π’ [5] ν΄λμ€ μμ (λΆλͺ¨ β μμ)
************************************************/
class DiscountProduct extends ProductClass {
constructor(code, name, price, discountRate) {
super(code, name, price); // λΆλͺ¨ νΈμΆ
this.discountRate = discountRate; // μΆκ° μμ±
}
getDiscountedPrice() {
const discounted = this.price * (1 - this.discountRate / 100);
console.log(`πΈ ν μΈ μ μ©κ°: ${discounted}μ`);
return discounted;
}
}
let dp1 = new DiscountProduct('A2001', 'νΌμ', 10000, 20);
dp1.showInfo();
dp1.getDiscountedPrice();
/************************************************
* π’ [6] μ μ λ©μλ (ν΄λμ€ μ체μμ νΈμΆ)
************************************************/
class Utility {
static sayHello() {
console.log('π μλ
νμΈμ! (μ μ λ©μλ)');
}
}
Utility.sayHello(); // κ°μ²΄ μμ± μμ΄ νΈμΆ κ°λ₯
/************************************************
* π’ [7] κ°μ²΄ λΉκ΅ (μ°Έμ‘°ν λΉκ΅ μ£Όμ)
************************************************/
let obj1 = new ProductClass('A1006', 'κ³Όμ', 2200);
let obj2 = new ProductClass('A1006', 'κ³Όμ', 2200);
console.log('πΈobj1 === obj2 ?', obj1 === obj2); // false (λ€λ₯Έ λ©λͺ¨λ¦¬)
let obj3 = obj1; // μ°Έμ‘° 볡μ¬
console.log('πΈobj1 === obj3 ?', obj1 === obj3); // true (κ°μ μ°Έμ‘°)
/************************************************
* π’ [8] λμ μμ± μΆκ° & μμ
************************************************/
obj1.category = 'μν'; // μΆκ°
console.log('πΈobj1μ category μΆκ°:', obj1);
delete obj1.category; // μμ
console.log('πΈobj1μμ category μμ :', obj1);
/************************************************
* π’ [9] κ³ κΈ: κ°μ²΄ μμ± μ΄κ±° & ν€/κ° μ κ·Ό
************************************************/
console.log('π κ°μ²΄μ μμ± μ΄κ±° (for...in):');
for (let key in obj2) {
console.log(`π ${key} : ${obj2[key]}`);
}
// ν€/κ° λ°°μ΄λ‘
console.log('π Object.keys:', Object.keys(obj2));
console.log('π Object.values:', Object.values(obj2));
console.log('π Object.entries:', Object.entries(obj2));
/************************************************
* π’ [10] κ³ κΈ: κ°μ²΄ λ³΅μ¬ (μμ λ³΅μ¬ vs κΉμ 볡μ¬)
************************************************/
const original = { code: 'X1', name: 'μ€λ΅', price: 1500, details: { origin: 'Korea' } };
// μμ λ³΅μ¬ (μ°Έμ‘° 곡μ )
const shallowCopy = { ...original };
shallowCopy.details.origin = 'USA';
console.log('πΈμλ³Έ κ°μ²΄:', original); // originλ λ°λ (μ°Έμ‘° 곡μ )
// κΉμ λ³΅μ¬ (JSON μ¬μ©)
const deepCopy = JSON.parse(JSON.stringify(original));
deepCopy.details.origin = 'Japan';
console.log('πΈμλ³Έ κ°μ²΄ (κΉμ λ³΅μ¬ ν):', original);
console.log('πΈκΉμ λ³΅μ¬ κ°μ²΄:', deepCopy);
</script>
</body>
</html>