๐งฌ 04. ํ๋กํ ํ์ & ์์ โ JS๊ฐ ํด๋์ค๋ฅผ ํ๋ด ๋ด๋ ์ง์ง ๋ฐฉ๋ฒ
๐ ๊ฐ์
JS์ ๋ณธ์ง์ธ ํ๋กํ ํ์ ์ฒด์ธ, Object.create, ํด๋์ค ๋ฌธ๋ฒ์ ๋ด๋ถ ๋์, ์ค๋ฌด์์์ ์์ ํจํด์ ์์ ์ ๋ณตํฉ๋๋ค.
๐ฏ ์ด ์น์ ์ ์ฝ๊ณ ๋๋ฉด:
- ํ๋กํ ํ์ ์ฒด์ธ์ด ์์ฑ ํ์์ ์ด๋ป๊ฒ ํ๋์ง ๋จธ๋ฆฟ์์ ๊ทธ๋ฆด ์ ์๋ค.
class๋ฌธ๋ฒ์ด ํ๋กํ ํ์ ์ ๋ฌธ๋ฒ์ ์คํ(syntactic sugar)์์ ์ค๋ช ํ ์ ์๋ค.Object.create,Object.getPrototypeOf๋ฑ ์ค๋ฌด API๋ฅผ ํ์ฉํ๋ค.
๐ ๋ชฉ์ฐจ
- ๐ ์ด ๋ฌธ์๋ฅผ ์ฝ๊ธฐ ์ ์
- ๐ค 1. ์ ์์์ผ ํ๋๊ฐ?
- ๐ 2. ํ๋กํ ํ์ ์ฒด์ธ์ ๋ณธ์ง
- ๐ญ 3. ์์ ๊ตฌํ ๋ฐฉ๋ฒ 3๊ฐ์ง
- ๐ 4. ์ค๋ฌด์์ ์์์ผ ํ ํ๋กํ ํ์ API
- โ ๏ธ 5. ํ๋กํ ํ์ ์ํฐํจํด
- ๐ ๋ง๋ฌด๋ฆฌ ํด์ฆ
- ๐ฃ ์์ฒ ์ด์ ํด๊ทผ ์ผ๊ธฐ
- ๐ ๋ ์์๋ณด๊ธฐ
๐ ์ด ๋ฌธ์๋ฅผ ์ฝ๊ธฐ ์ ์
โฑ๏ธ ์์ ์ฝ๊ธฐ ์๊ฐ: 20๋ถ(์ ์ฒด) / ํต์ฌ ํํธ๋ง: 12๋ถ
๐บ๏ธ ์ด ๋ฌธ์์ ํ๋ฆ
[ํ๋กํ ํ์
์ฒด์ธ ์ดํด] โ [์์ ๊ตฌํ 3๊ฐ์ง ๋ฐฉ๋ฒ] โ [์ค๋ฌด API] โ [์ํฐํจํด ์ฃผ์]
๐ฏ ์ด ๋ฌธ์๋ฅผ ๋ค ์ฝ์ผ๋ฉด ํ ์ ์๋ ๊ฒ
- "
arr.map์ ์ด๋์ ์ค๋๊ฐ?"๋ฅผ ํ๋กํ ํ์ ์ฒด์ธ์ผ๋ก ์ค๋ช ํ๋ค. - ES6
class๊ฐ ๋ด๋ถ์ ์ผ๋ก ์ด๋ป๊ฒ ๋์ํ๋์ง ์๊ณ ์ฝ๋๋ฅผ ์์ฑํ๋ค. -
instanceof,hasOwnProperty๋ฅผ ์ฌ๋ฐ๋ฅด๊ฒ ์ฌ์ฉํ๋ค.
๐บ๏ธ ์ด ๋ฌธ์์ ๋ฐฐ๊ฒฝ ์ธ๊ณ๊ด: '์์๋ค ์ปค๋ฎค๋ํฐ'
๐ฃ ์์ฒ : "์ํธ ๋! ์ค๋
class๋ก User, AdminUser๋ฅผ ๋ง๋ค์๋๋ฐ์. ํ์ ์คํฌ๋ฆฝํธ ์๋ฌ๋ ์๊ณ ์ ๋๋ ๊ฒ ๊ฐ์์ ์ ๋ฌ๋๋ฐ, ์ฝ๋ ๋ฆฌ๋ทฐ์์ 'ํ๋กํ ํ์ ์ฒด์ธ์ ์ดํดํ๊ณ class๋ฅผ ์ฐ๋ ๊ฑด์ง ํ์ธ ํ์'๋ผ๋ ์ฝ๋ฉํธ๊ฐ ๋ฌ๋ ธ์ด์. class ์ฐ๋ฉด ๋๋ ๊ฑฐ ์๋๊ฐ์? ์ ํ๋กํ ํ์ ์ ์์์ผ ํด์?"
๐ฆ ์ํธ: "class๋ JS๊ฐ ์๋ ๊ฐ์ง ํ๋กํ ํ์ ๊ธฐ๋ฐ ์์์ ์์ ์ท์ ์ ํ ๊ฑฐ์ผ. ๋ด๋ถ๋ ๋๊ฐ์ด ํ๋กํ ํ์ ์ฒด์ธ์ผ๋ก ๋์ํด. ๊ทธ ๋ด๋ถ๋ฅผ ๋ชจ๋ฅด๋ฉด, ๋ฉ๋ชจ๋ฆฌ ์ต์ ํ ์ ๋๊ณ , ์์์น ๋ชปํ ์์ฑ ๊ณต์ ๋ฒ๊ทธ ๋ง๋๊ณ , ๋๋ฒ๊น ํ ๋ chrome devtools์
[[Prototype]]๋ณด๋ฉด์ ๋ฉ๋ถํ๊ฒ ๋ผ. ํ ๋ฒ ์ ๋๋ก ์ดํดํ๋ฉด class๊ฐ ๋ ์ ๋ณด์ฌ."
๐ค 1. ์ ์์์ผ ํ๋๊ฐ?
์ํธ ๋ฆฌ๋ ๋์ด ์ฝ๋ ๋ฆฌ๋ทฐ์์ ์์ฒ ์ด์๊ฒ ๋ฌผ์์ต๋๋ค. "arr.map()์ด ๋๋์ฒด ์ด๋์ ํ์ด๋์จ ๊ฑด์ง ์ค๋ช
ํ ์ ์๋์?" ์์ฒ ์ด๋ ์ ๋ป ๋๋ตํ์ง ๋ชปํ์ฃ . ์ฐ๋ฆฌ๊ฐ ๋งค์ผ ๊ณต๊ธฐ์ฒ๋ผ ์ฌ์ฉํ๋ ๋ฐฐ์ด ๋ฉ์๋๋ค์ ๊ณ ํฅ์ ์ฐพ์๊ฐ๋ ์ฌ์ ์ด ๋ฐ๋ก ํ๋กํ ํ์
์ฒด์ธ์ ์ดํดํ๋ ๊ณผ์ ์
๋๋ค.
const arr = [1, 2, 3];
arr.map(x => x * 2); // [2, 4, 6] โ map์ ์ด๋์ ์๋๊ฐ?
arr.filter(x => x > 1); // [2, 3] โ filter๋ ์ด๋์ ์๋๊ฐ?arr๋ฅผ ์ง์ ์ ์ธํ์ ๋ map์ด๋ filter๋ฅผ ์ ์ํ ์ ์ด ์๋ค. ๊ทธ๋ฐ๋ฐ ์ ์ธ ์ ์์๊น?
๋ต: ํ๋กํ ํ์
์ฒด์ธ. arr์ [[Prototype]]์ด Array.prototype์ ๊ฐ๋ฆฌํค๊ณ , ๊ฑฐ๊ธฐ์ map, filter, reduce๊ฐ ์ ์๋์ด ์๊ธฐ ๋๋ฌธ์ด๋ค. ์ด ๋ฉ์ปค๋์ฆ์ด JS์ ์์ ์ด๋ค.
๐ 2. ํ๋กํ ํ์ ์ฒด์ธ์ ๋ณธ์ง
[[Prototype]] ๋ด๋ถ ์ฌ๋กฏ
์๋ฐ์คํฌ๋ฆฝํธ์ ๋ชจ๋ ๊ฐ์ฒด๋ ์๋ฐํ ํต๋ก๋ฅผ ํ๋์ฉ ๊ฐ์ง๊ณ ์์ต๋๋ค. ๋ฐ๋ก [[Prototype]]์ด๋ผ ๋ถ๋ฆฌ๋ ๋ด๋ถ ์ฌ๋กฏ์ด์ฃ . ์ด ํต๋ก๊ฐ ์ด๋ป๊ฒ ์ฐ๊ฒฐ๋์ด ์๋์ง ์ง์ ํ์ธํด ๋ณด๊ฒ ์ต๋๋ค.
const user = { name: "์์ฒ ", role: "junior" };
// user์ ํ๋กํ ํ์
์ฒด์ธ:
// user โ Object.prototype โ null
console.log(Object.getPrototypeOf(user) === Object.prototype); // true
console.log(Object.getPrototypeOf(Object.prototype)); // null (์ฒด์ธ์ ๋)
// user๋ ์ง์ ์ ์ธํ์ง ์์์ง๋ง Object.prototype์ ๋ฉ์๋๋ฅผ ์ธ ์ ์๋ค
user.toString(); // "[object Object]" โ Object.prototype.toString
user.hasOwnProperty("name"); // true โ Object.prototype.hasOwnProperty์์ฑ ํ์ ์์
๊ฐ์ฒด์์ ์ด๋ค ๊ฐ์ ์ฐพ์ ๋, ์์ง์ ๋ฐฉ๊ธ ๋ณธ '์๋ฐํ ํต๋ก'๋ฅผ ํ๊ณ ๋ถ๋ชจ๋ค์ ์ฐพ์ ์ฌ๋ผ๊ฐ๋๋ค. ์์๋ค ์ปค๋ฎค๋ํฐ์ ์ ์ ๊ถํ ์ฒดํฌ ๋ก์ง์ ์๋ก ๋ค์ด ํ์ ๊ณผ์ ์ ๊ทธ๋ ค๋ณด๊ฒ ์ต๋๋ค.
// ์์๋ค ์ปค๋ฎค๋ํฐ โ ์ ์ ์ญํ ๊ถํ ์ฒดํฌ
function User(name) {
this.name = name; // ์ธ์คํด์ค ์ง์ ์์ฑ
}
User.prototype.role = "member"; // ํ๋กํ ํ์
์์ฑ
User.prototype.canPost = function () {
return true; // ํ๋กํ ํ์
๋ฉ์๋ (๋ชจ๋ ์ธ์คํด์ค๊ฐ ๊ณต์ )
};
const yc = new User("์์ฒ ");
const yh = new User("์ํธ");
// ์์ฑ ํ์ ์์:
// 1. ์ธ์คํด์ค ์ง์ ์์ฑ ํ์
// 2. ์์ผ๋ฉด [[Prototype]] (User.prototype) ํ์
// 3. ์์ผ๋ฉด Object.prototype ํ์
// 4. ์์ผ๋ฉด undefined
console.log(yc.name); // "์์ฒ " โ ์ธ์คํด์ค ์ง์ โ
console.log(yc.role); // "member" โ User.prototype์์ ๋ฐ๊ฒฌ
console.log(yc.canPost()); // true โ User.prototype์์ ๋ฐ๊ฒฌ
// ์ธ์คํด์ค์ ์ง์ ์ค์ ํ๋ฉด ํ๋กํ ํ์
์ ๊ฐ๋ฆฐ๋ค (Shadowing)
yc.role = "admin"; // yc ์ธ์คํด์ค์ ์ง์ ์ถ๊ฐ
console.log(yc.role); // "admin" โ ์ธ์คํด์ค ์ง์ ์์ฑ์ด ์ฐ์
console.log(yh.role); // "member" โ yh๋ ๊ทธ๋๋ก ํ๋กํ ํ์
์ฐธ์กฐ
// ํ๋กํ ํ์
๋ฉ์๋๋ ๋ชจ๋ ์ธ์คํด์ค๊ฐ ๊ณต์ (๋ฉ๋ชจ๋ฆฌ ํจ์จ)
console.log(yc.canPost === yh.canPost); // true โ ๋์ผํ ํจ์ ์ฐธ์กฐ!๋ฉ๋ชจ๋ฆฌ ํจ์จ์ ํต์ฌ: ๋ฉ์๋๋ฅผ
prototype์ ์ ์ํ๋ฉด ๋ชจ๋ ์ธ์คํด์ค๊ฐ ํ๋์ ํจ์ ๋ฅผ ๊ณต์ ํ๋ค. ์์ฑ์ ์์ ์ ์ํ๋ฉด ์ธ์คํด์ค๋ง๋ค ์ ํจ์๊ฐ ์์ฑ๋๋ค.
๐ญ 3. ์์ ๊ตฌํ ๋ฐฉ๋ฒ 3๊ฐ์ง
์์ฑ์ ํจ์ + prototype
๋ณธ๊ฒฉ์ ์ธ ํด๋์ค ๋ฌธ๋ฒ์ด ๋ฑ์ฅํ๊ธฐ ์ , ์ ๋ฐฐ ๊ฐ๋ฐ์๋ค์ด ํ๋กํ ํ์ ์ฒด์ธ์ ์ง์ ์ฐ๊ฒฐํ๋ฉฐ ์์์ ๊ตฌํํ๋ ๋ฐฉ์์ ๋๋ค.
// ๊ธฐ๋ฐ ์์ฑ์
function User(name, email) {
this.name = name;
this.email = email;
}
User.prototype.login = function () {
console.log(`${this.name} ๋ก๊ทธ์ธ`);
};
// AdminUser๊ฐ User๋ฅผ ์์
function AdminUser(name, email, permissions) {
User.call(this, name, email); // ๋ถ๋ชจ ์์ฑ์ ํธ์ถ (this ๋ฐ์ธ๋ฉ ์ด์ )
this.permissions = permissions;
}
// ํ๋กํ ํ์
์ฒด์ธ ์ฐ๊ฒฐ
AdminUser.prototype = Object.create(User.prototype);
AdminUser.prototype.constructor = AdminUser; // constructor ๋ณต๊ตฌ
AdminUser.prototype.manage = function () {
console.log(`${this.name}์ด ๊ด๋ฆฌ์ ๊ถํ์ผ๋ก ๊ด๋ฆฌ ์ค`);
};
const admin = new AdminUser("์ํธ", "yh@example.com", ["delete", "ban"]);
admin.login(); // "์ํธ ๋ก๊ทธ์ธ" โ User.prototype ๋ฉ์๋
admin.manage(); // "์ํธ์ด ๊ด๋ฆฌ์ ๊ถํ์ผ๋ก ๊ด๋ฆฌ ์ค" โ AdminUser.prototype ๋ฉ์๋
// ํ๋กํ ํ์
์ฒด์ธ:
// admin โ AdminUser.prototype โ User.prototype โ Object.prototype โ nullObject.create
๊ฐ์ฅ ์์ํ๊ฒ "์ด ๊ฐ์ฒด๋ฅผ ๋ถ๋ชจ๋ก ์ผ์์ค"๋ผ๊ณ ๋ช ์ํ๋ฉฐ ์๋ก์ด ๊ฐ์ฒด๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ์ ๋๋ค.
const userMethods = {
login() {
console.log(`${this.name} ๋ก๊ทธ์ธ`);
},
logout() {
console.log(`${this.name} ๋ก๊ทธ์์`);
},
};
// userMethods๋ฅผ ํ๋กํ ํ์
์ผ๋ก ๊ฐ์ง๋ ์ ๊ฐ์ฒด ์์ฑ
const yc = Object.create(userMethods);
yc.name = "์์ฒ ";
yc.email = "yc@example.com";
yc.login(); // "์์ฒ ๋ก๊ทธ์ธ" โ ํ๋กํ ํ์
๋ฉ์๋
// ๊ด๋ฆฌ์ โ userMethods๋ฅผ ์์ํ๋ฉด์ ์ถ๊ฐ ๋ฉ์๋ ๋ณด์
const adminMethods = Object.create(userMethods);
adminMethods.manage = function () {
console.log(`${this.name}์ด ๊ด๋ฆฌ ์ค`);
};
const yh = Object.create(adminMethods);
yh.name = "์ํธ";
yh.login(); // "์ํธ ๋ก๊ทธ์ธ" โ userMethods ์ฒด์ธ์ ํตํด
yh.manage(); // "์ํธ์ด ๊ด๋ฆฌ ์ค"
// ์ฒด์ธ: yh โ adminMethods โ userMethods โ Object.prototype โ nullclass (ES6+)
"๋ด๋ถ ๋์์ ํ๋กํ ํ์ ์ด๋ ์์ ํ ๊ฐ์์. ๋จ์ง ๋ฌธ๋ฒ์ด ๋ ์ฝ๊ธฐ ์ข์ ๋ฟ์ด์์." ์ํธ ๋ฆฌ๋ ๋์ ์กฐ์ธ์ ๋ฐ์ํด ์์ฒ ์ด๊ฐ ํ๋์ ์ธ ํด๋์ค ๋ฌธ๋ฒ์ผ๋ก ๋ฆฌํฉํ ๋งํ ๊ฒฐ๊ณผ๋ฌผ์ ๋๋ค.
// โ
ํ๋์ ์ด๊ณ ๊ถ์ฅ๋๋ ๋ฐฉ๋ฒ
class User {
// constructor ๋ด๋ถ = ์ธ์คํด์ค ์ง์ ์์ฑ
constructor(name, email) {
this.name = name;
this.email = email;
}
// ํด๋์ค ๋ณธ๋ฌธ์ ๋ฉ์๋ = User.prototype์ ์ ์๋จ
login() {
console.log(`${this.name} ๋ก๊ทธ์ธ`);
}
// static = User ์์ฒด์ ๋ฉ์๋ (์ธ์คํด์ค์์ ํธ์ถ ๋ถ๊ฐ)
static createGuest() {
return new User("๊ฒ์คํธ", "guest@example.com");
}
}
class AdminUser extends User {
constructor(name, email, permissions) {
super(name, email); // ๋ถ๋ชจ constructor ํธ์ถ (ํ์!)
this.permissions = permissions;
}
manage() {
console.log(`${this.name}์ด ๊ด๋ฆฌ ์ค`);
}
// ๋ถ๋ชจ ๋ฉ์๋ ์ค๋ฒ๋ผ์ด๋
login() {
super.login(); // ๋ถ๋ชจ login ํธ์ถ
console.log("(๊ด๋ฆฌ์ ๊ถํ์ผ๋ก ์ ์)");
}
}
const admin = new AdminUser("์ํธ", "yh@example.com", ["delete"]);
admin.login();
// "์ํธ ๋ก๊ทธ์ธ"
// "(๊ด๋ฆฌ์ ๊ถํ์ผ๋ก ์ ์)"
// ๋ด๋ถ์ ์ผ๋ก ์ฌ์ ํ ํ๋กํ ํ์
์ฒด์ธ!
console.log(Object.getPrototypeOf(AdminUser.prototype) === User.prototype); // true
console.log(admin instanceof User); // true
console.log(admin instanceof AdminUser); // true๐ 4. ์ค๋ฌด์์ ์์์ผ ํ ํ๋กํ ํ์ API
// hasOwnProperty โ ํ๋กํ ํ์
์ฒด์ธ ์ ์ธ, ์ง์ ์์ฑ๋ง ํ์ธ
const user = { name: "์์ฒ " };
user.hasOwnProperty("name"); // true โ ์ง์ ์์ฑ
user.hasOwnProperty("toString"); // false โ Object.prototype์ ์์
// ๊ถ์ฅ: Object.hasOwn (ES2022, hasOwnProperty๋ณด๋ค ์์ )
Object.hasOwn(user, "name"); // true
// instanceof โ ํ๋กํ ํ์
์ฒด์ธ์ ํน์ prototype์ด ์๋์ง ํ์ธ
const admin = new AdminUser("์ํธ", "yh@example.com", []);
admin instanceof AdminUser; // true
admin instanceof User; // true โ ํ๋กํ ํ์
์ฒด์ธ์ User.prototype ์์
admin instanceof Array; // false
// Object.getPrototypeOf โ ํ๋กํ ํ์
์ ๊ทผ (๊ถ์ฅ)
Object.getPrototypeOf(admin) === AdminUser.prototype; // true
// Object.keys vs for...in
const post = Object.create({ type: "post" }); // type์ ํ๋กํ ํ์
post.title = "ํด๋ก์ ";
post.author = "์์ฒ ";
Object.keys(post); // ["title", "author"] โ ์ง์ ์์ฑ๋ง
for (const key in post) console.log(key); // title, author, type โ ์ฒด์ธ ํฌํจ!
// โ for...in ๋ฃจํ์์ hasOwnProperty ์ฒดํฌ๊ฐ ํ์ํ ์ด์ โ ๏ธ 5. ํ๋กํ ํ์ ์ํฐํจํด
์ํธ ๋ฆฌ๋ ๋์ด ์คํ์์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ถ์ํ๋ฉฐ ํ์๋ค์๊ฒ ์ ๋๋ก ๋ฐ๋ผ ํ์ง ๋ง๋ผ๊ณ ๊ฐ์กฐํ ์ฌ๋ก๋ค์ ๋๋ค. "ํธ๋ฆฌํจ ๋ค์ ์จ์ ์ํ์ ๋ณผ ์ค ์์์ผ ํ๋ค"๋ ์ํธ ๋์ ๋ง์ ๊ธฐ์ตํ๋ฉฐ ์ดํด๋ณด์ธ์.
// โ ์ ๋ ํ๋ฉด ์ ๋๋ ๊ฒ: ๋ด์ฅ ํ๋กํ ํ์
์์ (Monkey Patching)
Array.prototype.sum = function () {
return this.reduce((acc, val) => acc + val, 0);
};
[1, 2, 3].sum(); // 3 โ ๋์ํ์ง๋ง...
// ์ด ์ฝ๋๊ฐ ์ ์ํํ๊ฐ?
// 1. ๋ค๋ฅธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ๋๊ฐ์ ์ด๋ฆ์ผ๋ก sum์ ์ถ๊ฐํ๋ค๋ฉด โ ์๊ธฐ์น ๋ชปํ ์ถฉ๋
// 2. ๋ฏธ๋์ ์๋ฐ์คํฌ๋ฆฝํธ ํ์ค์ Array.prototype.sum์ด ์๊ธด๋ค๋ฉด โ ํ์ค ๋์์ ๋ฐฉํดํจ
// 3. ํ์๋ค์ด sum์ ํ์ค ๋ฉ์๋๋ก ์คํดํ์ฌ ํผ๋์ ์ค
// โ
๋์ ์ ํธ ํจ์๋ก ๋ถ๋ฆฌ
const arrayUtils = {
sum(arr) {
return arr.reduce((acc, val) => acc + val, 0);
},
};
arrayUtils.sum([1, 2, 3]); // 3 โ
// โ __proto__ ์ง์ ์์ โ ์ฑ๋ฅ ์ ํ ๋ฐ ์์ธก ๋ถ๊ฐ
const obj = {};
obj.__proto__ = { greeting: "hello" }; // JS ์์ง์ด ๊ฐ์ฒด ํํ๋ฅผ ์ฌ๊ตฌ์ฑ
// โ
Object.create ๋๋ Object.setPrototypeOf ์ฌ์ฉ (๊ทธ๋๋ง ๋ซ์ง๋ง ์ ์คํ๊ฒ)
const proto = { greeting: "hello" };
const obj2 = Object.create(proto);๐ ๋ง๋ฌด๋ฆฌ ํด์ฆ
Q1. ์๋ ์ฝ๋์์ yc.canPost()๊ฐ ์ ์ ๋์ํ๋ ์ด์ ๋ฅผ ํ๋กํ ํ์
์ฒด์ธ์ผ๋ก ์ค๋ช
ํ๋ผ.
function User(name) {
this.name = name;
}
User.prototype.canPost = function () { return true; };
const yc = new User("์์ฒ ");
console.log(yc.canPost()); // trueโ
์ ๋ต: yc ์ธ์คํด์ค์๋ canPost๊ฐ ์์ง๋ง, [[Prototype]]์ธ User.prototype์์ ๋ฐ๊ฒฌ๋์ด ์คํ๋๋ค.
๐ก ์์ธ ํด์ค:
new User("์์ฒ ")์คํ ์,yc.[[Prototype]] = User.prototype์ผ๋ก ์ฐ๊ฒฐ๋๋ค.yc.canPost์ ๊ทผ ์: โyc์ง์ โ ์์ โกUser.prototypeโcanPost๋ฐ๊ฒฌ โ- ์ด ๊ณผ์ ์ด ํ๋กํ ํ์
์ฒด์ธ ํ์ ์ด๋ค. ๋ฐ๊ฒฌ๋ ๋๊น์ง ์ฒด์ธ์ ํ๊ณ ์ฌ๋ผ๊ฐ๋ฉฐ,
null์ ๋๋ฌํ๋ฉดundefined๋ฅผ ๋ฐํํ๋ค. - ๐ ํต์ฌ ๊ธฐ์ต๋ฒ: "๋ด ์ฃผ๋จธ๋์ ์์ผ๋ฉด ๋ถ๋ชจ๋์ ์ฃผ๋จธ๋๋ฅผ ์ฐพ์๋ณด์ธ์. ๋ถ๋ชจ๋๋ ์์ผ๋ฉด ํ ์๋ฒ์ง๊ป ๋ฌผ์ด๋ณด๋ ์์ด์ฃ . ์ด ์ฌ์ ์ด ๋๋๋ ์ง์ (null)๊น์ง ๋ฐ๊ฒฌ๋์ง ์๋๋ค๋ฉด, ๊ทธ๋์์ผ
undefined๋ฅผ ๋ฐ๊ฒ ๋ฉ๋๋ค."
Q2. ๋ฉ์๋๋ฅผ prototype์ ์ ์ํ๋ ๊ฒ๊ณผ ์์ฑ์ ํจ์ ๋ด๋ถ์ ์ ์ํ๋ ๊ฒ์ ์ฐจ์ด๋?
โ
์ ๋ต: prototype์ ์ ์ํ๋ฉด ๋ชจ๋ ์ธ์คํด์ค๊ฐ ํ๋์ ํจ์๋ฅผ ๊ณต์ (๋ฉ๋ชจ๋ฆฌ ํจ์จ), ์์ฑ์ ๋ด๋ถ์ ์ ์ํ๋ฉด ์ธ์คํด์ค๋ง๋ค ์๋ก์ด ํจ์ ์์ฑ (๋ฉ๋ชจ๋ฆฌ ๋ญ๋น).
๐ก ์์ธ ํด์ค:
// โ ์์ฑ์ ๋ด๋ถ โ ์ธ์คํด์ค๋ง๋ค ์ ํจ์ ์์ฑ (100๊ฐ ์ธ์คํด์ค = ํจ์ 100๊ฐ)
function User(name) {
this.name = name;
this.greet = function() { console.log(this.name); }; // ๋งค๋ฒ ์ ํจ์
}
// โ
prototype โ ๋ชจ๋ ์ธ์คํด์ค๊ฐ ๊ณต์ (100๊ฐ ์ธ์คํด์ค = ํจ์ 1๊ฐ)
function User(name) {
this.name = name;
}
User.prototype.greet = function() { console.log(this.name); };- ์ธ์คํด์ค๊ฐ ๋ง์์ง์๋ก
prototype๋ฐฉ์์ ๋ฉ๋ชจ๋ฆฌ ํจ์จ์ด ์๋์ ์ด๋ค. class๋ฌธ๋ฒ์ ๋ฉ์๋๋ ์๋์ผ๋กprototype์ ์ ์๋๋ค.- ๐ ํต์ฌ ๊ธฐ์ต๋ฒ: "์ธ์คํด์ค๋ง๋ค ๋ฌ๋ผ์ผ ํ๋ ๊ฒ์ ์์ฑ์์, ๊ณตํต์ผ๋ก ์ฐ์ด๋ ๊ฒ์ prototype์."
Q3. ์์ฒ ์ด์ ํ ์คํธ ํ์ โ ์ํคํ ์ฒ ์ค๊ณ
์์ PM์ด ์๊ตฌ์ฌํญ์ ์ ๋ฌํ๋ค: "User, AdminUser, GuestUser ์ธ ์ข ๋ฅ์ ์ ์ ๋ฅผ ๋ง๋ค์ด์ผ ํด์. ๊ณตํต ๊ธฐ๋ฅ(login, logout)์ ์ค๋ณต ์์ด ์จ์ผ ํ๊ณ , AdminUser๋ manage ๊ธฐ๋ฅ, GuestUser๋ ์ ํ์ ๊ธฐ๋ฅ๋ง ๊ฐ๋๋ก ์ค๊ณํด์ฃผ์ธ์."
์์ฒ ์ด๊ฐ ES6 class๋ฅผ ์ฌ์ฉํด ์ค๊ณํ๋๋ฐ, ์ด๋ค ๊ตฌ์กฐ๊ฐ ์ฌ๋ฐ๋ฅธ๊ฐ?
โ
์ ๋ต: User ํด๋์ค์ ๊ณตํต ๋ฉ์๋๋ฅผ ๋๊ณ , AdminUser extends User, GuestUser extends User๋ก ์์ ๊ตฌ์กฐ๋ฅผ ๋ง๋ ๋ค.
๐ก ์์ธ ํด์ค:
class User {
constructor(name, email) {
this.name = name;
this.email = email;
}
login() { console.log(`${this.name} ๋ก๊ทธ์ธ`); }
logout() { console.log(`${this.name} ๋ก๊ทธ์์`); }
}
class AdminUser extends User {
constructor(name, email, permissions) {
super(name, email);
this.permissions = permissions;
}
manage() { console.log(`${this.name} ๊ด๋ฆฌ ์ค`); }
}
class GuestUser extends User {
constructor() {
super("๊ฒ์คํธ", "guest@example.com");
}
login() { // ์ค๋ฒ๋ผ์ด๋ โ ์ ํ๋ ๊ถํ ๋ฉ์์ง
console.log("๊ฒ์คํธ๋ก ์ ํ์ ์ ๊ทผํฉ๋๋ค.");
}
}login/logout์User.prototype์ ํ ๋ฒ๋ง ์ ์ โ ์ฝ๋ ์ค๋ณต ์ ๊ฑฐAdminUser,GuestUser๋ ํ์ํ ๊ฒ๋ง ์ถ๊ฐ/์ค๋ฒ๋ผ์ด๋- ๐ ํต์ฌ ๊ธฐ์ต๋ฒ: "๊ณตํต์ ์๋ก(๋ถ๋ชจ), ํน์๋ ์๋๋ก(์์). ์ค๋ณต ์ฝ๋๊ฐ ๋ณด์ด๋ฉด ๋ถ๋ชจ ํด๋์ค๋ก ๋์ด์ฌ๋ ค๋ผ."
๐ฃ ์์ฒ ์ด์ ํด๊ทผ ์ผ๊ธฐ
์ค๋์ ์ง์ง ๋๋๊ฐ ๊ณผ์ด๋ ๊ฒ ๊ฐ๋ค. ํ๋กํ ํ์
์ด ๊ทธ๋ฅ "๋ญ๊ฐ ๋ถ๋ชจ ๊ฐ๋
" ์ ๋๋ก ์์๋๋ฐ, ์ค์ ๋ก [[Prototype]] ์ฌ๋กฏ์ด ๊ฐ์ฒด๋ผ๋ฆฌ ์ฐ๊ฒฐ๋๋ ๊ตฌ์กฐ๋ผ๋ ๊ฒ ์ ๊ธฐํ๋ค. ๊ทธ๋ฆฌ๊ณ ๋ด๊ฐ ๋งค์ผ ์ฐ๋ arr.map()์ด ์ฌ์ค Array.prototype.map์ ์ฒด์ธ์ผ๋ก ์ฐพ์๊ฐ๋ ๊ฑฐ์๋ค๋...
์ํธ ๋์ด "class๋ ์ท๋ง ๋ฐ๊ฟ์ ์ ํ๋กํ ํ์ "์ด๋ผ๊ณ ํ๋๋ฐ, ์ฒ์์ ๋ฌด์จ ๋ง์ธ์ง ๋ชฐ๋๋ค. ์ง๊ธ์ ์์ ํ ์ดํด๊ฐ ๋๋ค. ์์ด ๋ณด์ด๋๊น class๊ฐ ๋ ๋ฏฟ์์ง์ค๋ฝ๊ฒ ๋๊ปด์ง๋ค.
๐ก ์ค๋์ ๊ตํ: "์๋ฐ์คํฌ๋ฆฝํธ์ ์์์ ๋ฐ์ดํฐ๋ฅผ ํต์งธ๋ก ๋ณต์ฌํ๋ ๊ฒ์ด ์๋๋ผ 'ํต๋ก๋ก ์ฐ๊ฒฐ'ํ๋ ๊ฒ์ ๋๋ค. ์ธ์คํด์ค๋ ๋ชจ๋ ๋ฌด๊ธฐ๋ฅผ ์ง์ ๋ค๊ณ ๋ค๋๋ ๋์ , ํ์ํ ๋๋ง๋ค ํ๋กํ ํ์ ์ฒด์ธ์ด๋ผ๋ ์ฐฝ๊ณ ์์ ๋น๋ ค ์๋๋ค."
์ค๋ ๊ณต๋ถ ์์ด ๋ง์์ ์ข ์ง์ณค๋ค. ํด๊ทผํ๊ณ ์นํจ ์์ผ์ ์ฌ์ด์ผ์ง. ๋ด์ผ์ ๋น๋๊ธฐ Promise ํธ์ธ๋ฐ, ์ด๊ฒ๋ ๋ง๋ง์น ์์ ๊ฒ ๊ฐ๋ค. ๊ทธ๋๋ ์ค๋์ฒ๋ผ ํ๋ฉด ์ด๋ป๊ฒ๋ ๋๊ฒ ์ง. ๋ด์ผ์ ๋, ํ์ดํ .