ê°ë°ì íë¤ ë³´ë©´ 기존ì ìë 기ë¥ì ê°ì ¸ì íì¥í´ì¼ íë ê²½ì°ê° ìê¹ëë¤.
ì¬ëì ê´í íë¡í¼í°ì ë©ìë를 ê°ì§ userë¼ë ê°ì²´ê° ìëë°, userì ìë¹í ì ì¬íì§ë§ ì½ê°ì ì°¨ì´ê° ìë adminê³¼ guest ê°ì²´ë¥¼ ë§ë¤ì´ì¼ íë¤ê³ ê°ì í´ ë´
ìë¤. ì´ë "userì ë©ìë를 ë³µì¬íê±°ë ë¤ì 구ííì§ ìê³ userì ì½ê°ì 기ë¥ì ì¹ì´ adminê³¼ guest ê°ì²´ë¥¼ ë§ë¤ ì ìì§ ììê¹?"ë¼ë ìê°ì´ ë¤ ê²ëë¤.
ìë°ì¤í¬ë¦½í¸ ì¸ì´ì ê³ ì 기ë¥ì¸ íë¡í íì ìì(prototypal inheritance) ì ì´ì©íë©´ ìì ê°ì ìê°ì ì¤íí ì ììµëë¤.
[[Prototype]]
ìë°ì¤í¬ë¦½í¸ì ê°ì²´ë ëª
ì¸ììì ëª
ëª
í [[Prototype]]ì´ë¼ë ì¨ê¹ íë¡í¼í°ë¥¼ ê°ìµëë¤. ì´ ì¨ê¹ íë¡í¼í° ê°ì nullì´ê±°ë ë¤ë¥¸ ê°ì²´ì ëí ì°¸ì¡°ê° ëëë°, ë¤ë¥¸ ê°ì²´ë¥¼ 참조íë ê²½ì° ì°¸ì¡° ëìì 'íë¡í íì
(prototype)'ì´ë¼ ë¶ë¦
ëë¤.
íë¡í íì
ì ëì ë°©ìì âì ë¹ì¤ë¬ì´â ë©´ì´ ììµëë¤. objectìì íë¡í¼í°ë¥¼ ì½ì¼ë ¤ê³ íëë° í´ë¹ íë¡í¼í°ê° ìì¼ë©´ ìë°ì¤í¬ë¦½í¸ë ìëì¼ë¡ íë¡í íì
ìì íë¡í¼í°ë¥¼ 찾기 ë문ì´ì£ . íë¡ê·¸ëë°ìì ì´ë° ëì ë°©ìì 'íë¡í íì
ììâì´ë¼ ë¶ë¦
ëë¤. ì¸ì´ ì°¨ììì ì§ìíë í¸ë¦¬í 기ë¥ì´ë ê°ë° í
í¬ë ì¤ íë¡í íì
ììì 기ë°í´ ë§ë¤ì´ì§ ê²ë¤ì´ ë§ìµëë¤.
[[Prototype]] íë¡í¼í°ë ë´ë¶ íë¡í¼í°ì´ë©´ì ì¨ê¹ íë¡í¼í°ì´ì§ë§ ë¤ìí ë°©ë²ì ì¬ì©í´ ê°ë°ìê° ê°ì ì¤ì í ì ììµëë¤.
ìë ììì²ë¼ í¹ë³í ì´ë¦ì¸ __proto__ì ì¬ì©íë©´ ê°ì ì¤ì í ì ììµëë¤.
let animal = {
eats: true
};
let rabbit = {
jumps: true
};
rabbit.__proto__ = animal;
__proto__ë [[Prototype]]ì© getter·setterì
ëë¤.__proto__ë [[Prototype]]ê³¼ ë¤ë¦
ëë¤. __proto__ë [[Prototype]]ì getter(íëì)ì´ì setter(ì¤ì ì) ì
ëë¤.
íì í¸íì± ë문ì ì¬ì í __proto__를 ì¬ì©í ì ìì§ë§ ë¹êµì ê·¼ëì ìì±ë ì¤í¬ë¦½í¸ìì __proto__ ëì í¨ì Object.getPrototypeOfë Object.setPrototypeOfì ì¨ì íë¡í íì
ì íë(get)íê±°ë ì¤ì (set)í©ëë¤. ê·¼ëì ì __proto__를 ì°ì§ ìëì§ì ë í¨ìì ìì¸í ì¤ëª
ì ëí´ì ì´ì´ì§ë ì±í°ìì ë¤ë£° ìì ì
ëë¤.
__proto__ë ë¸ë¼ì°ì íê²½ììë§ ì§ìíëë¡ ìë°ì¤í¬ë¦½í¸ ëª
ì¸ììì ê·ì íìëë°,
ì¤ìì ìë² ì¬ì´ë를 í¬í¨í 모ë í¸ì¤í¸ íê²½ìì __proto__를 ì§ìí©ëë¤. [[Prototype]]ë³´ë¤ë __proto__ê° ì¡°ê¸ ë ì§ê´ì ì´ì´ì ì´í´í기 ì¬ì°ë¯ë¡, 본 íí 리ì¼ì ìììì __proto__를 ì¬ì©íëë¡ íê² ìµëë¤.
ê°ì²´ rabbitìì íë¡í¼í°ë¥¼ ì»ê³ ì¶ìë° í´ë¹ íë¡í¼í°ê° ìë¤ë©´, ìë°ì¤í¬ë¦½í¸ë ìëì¼ë¡ animalì´ë¼ë ê°ì²´ìì íë¡í¼í°ë¥¼ ì»ìµëë¤.
ìì:
let animal = {
eats: true
};
let rabbit = {
jumps: true
};
rabbit.__proto__ = animal; // (*)
// íë¡í¼í° eatsê³¼ jumps를 rabbitììë ì¬ì©í ì ìê² ëììµëë¤.
alert( rabbit.eats ); // true (**)
alert( rabbit.jumps ); // true
(*)ë¡ íìí ì¤ìì animalì´ rabbitì íë¡í íì
ì´ ëëë¡ ì¤ì íììµëë¤.
(**)ë¡ íìí ì¤ìì alert í¨ìê° rabbit.eats íë¡í¼í°ë¥¼ ì½ì¼ë ¤ íëë°, rabbitì eatsë¼ë íë¡í¼í°ê° ììµëë¤. ì´ë ìë°ì¤í¬ë¦½í¸ë [[Prototype]]ì´ ì°¸ì¡°íê³ ìë ê°ì²´ì¸ animalìì eats를 ì»ì´ë
ëë¤. ë¤ì 그림ì ë°ììë¶í° ìë¡ ì´í´ë³´ì¸ì.
ì´ì ârabbitì íë¡í íì
ì animalì
ëë¤.â í¹ì "rabbitì animalì ììë°ëë¤."ë¼ê³ ë§ í ì ìê² ëììµëë¤.
íë¡í íì
ì ì¤ì í´ ì¤ ëë¶ì rabbitììë animalì 구íë ì ì©í íë¡í¼í°ì ë©ìë를 ì¬ì©í ì ìê² ëìë¤ì. ì´ë ê² íë¡í íì
ìì ììë°ì íë¡í¼í°ë¥¼ 'ìì íë¡í¼í°(inherited property)'ë¼ê³ í©ëë¤.
ìì íë¡í¼í°ë¥¼ ì¬ì©í´ animalì ì ìë ë©ìë를 rabbitìì í¸ì¶í´ ë´
ìë¤.
let animal = {
eats: true,
walk() {
alert("ëë¬¼ì´ ê±·ìµëë¤.");
}
};
let rabbit = {
jumps: true,
__proto__: animal
};
// ë©ìë walkë rabbitì íë¡í íì
ì¸ animalìì ììë°ììµëë¤.
rabbit.walk(); // ëë¬¼ì´ ê±·ìµëë¤.
ìë 그림과 ê°ì´ íë¡í íì
(animal)ìì walk를 ìëì¼ë¡ ììë°ì기 ë문ì rabbitììë walk를 í¸ì¶í ì ìê² ëììµëë¤.
íë¡í íì ì²´ì¸ì ì§ê¸ê¹ì§ ì´í´ë³¸ ììë¤ë³´ë¤ 길ì´ì§ ì ììµëë¤.
let animal = {
eats: true,
walk() {
alert("ëë¬¼ì´ ê±·ìµëë¤.");
}
};
let rabbit = {
jumps: true,
__proto__: animal
};
let longEar = {
earLength: 10,
__proto__: rabbit
};
// ë©ìë walkë íë¡í íì
ì²´ì¸ì íµí´ ììë°ììµëë¤.
longEar.walk(); // ëë¬¼ì´ ê±·ìµëë¤.
alert(longEar.jumps); // true (rabbitìì ììë°ì)
íë¡í íì ì²´ì´ëì ë ê°ì§ ì ì½ì¬íì´ ììµëë¤.
- ìí 참조(circular reference)ë íì©ëì§ ììµëë¤.
__proto__를 ì´ì©í´ ë«í ííë¡ ë¤ë¥¸ ê°ì²´ë¥¼ 참조íë©´ ìë¬ê° ë°ìí©ëë¤. __proto__ì ê°ì ê°ì²´ënullë§ ê°ë¥í©ëë¤. ë¤ë¥¸ ìë£íì 무ìë©ëë¤.
ì¬ê¸°ì ëíì¬ ê°ì²´ì ì¤ì§ íëì [[Prototype]]ë§ ìì ì ìë¤ë ë¹ì°í ì ì½ë ììµëë¤. ê°ì²´ë ë ê°ì ê°ì²´ë¥¼ ììë°ì§ 못í©ëë¤.
íë¡í íì ì ì½ê¸° ì ì©ì´ë¤
íë¡í íì ì íë¡í¼í°ë¥¼ ì½ì ëë§ ì¬ì©í©ëë¤.
íë¡í¼í°ë¥¼ ì¶ê°, ìì íê±°ë ì§ì°ë ì°ì°ì ê°ì²´ì ì§ì í´ì¼ í©ëë¤.
ê°ì²´ rabbitì ë©ìë walk를 ì§ì í ë¹í´ ë³´ê² ìµëë¤.
let animal = {
eats: true,
walk() {
/* rabbitì ì´ì ì´ ë©ìë를 ì¬ì©íì§ ììµëë¤. */
}
};
let rabbit = {
__proto__: animal
};
rabbit.walk = function() {
alert("í ë¼ê° 깡충깡충 ëëë¤.");
};
rabbit.walk(); // í ë¼ê° 깡충깡충 ëëë¤.
rabbit.walk()를 í¸ì¶íë©´ íë¡í íì
ì ìë ë©ìëê° ì¤íëì§ ìê³ , ê°ì²´ rabbitì ì§ì ì¶ê°í ë©ìëê° ì¤íë©ëë¤.
ê·¸ë°ë° ì ê·¼ì íë¡í¼í°(accessor property)ë setter í¨ì를 ì¬ì©í´ íë¡í¼í°ì ê°ì í ë¹íë¯ë¡ ì ê·¼ì íë¡í¼í°ì ê°ì í ë¹((**))íë©´ ê°ì²´(admin)ì íë¡í¼í°(fullName)ê° ì¶ê°ëëê² ìëë¼ setter í¨ìê° í¸ì¶ëë©´ì ì ìììë ì¡°ê¸ ë¤ë¥´ê² ëìí©ëë¤.
ìë ìììì admin.fullNameì´ ìëí ëë¡ ì ìëíëì§ íì¸í´ ë´
ìë¤.
let user = {
name: "John",
surname: "Smith",
set fullName(value) {
[this.name, this.surname] = value.split(" ");
},
get fullName() {
return `${this.name} ${this.surname}`;
}
};
let admin = {
__proto__: user,
isAdmin: true
};
alert(admin.fullName); // John Smith (*)
// setter í¨ìê° ì¤íë©ëë¤!
admin.fullName = "Alice Cooper"; // (**)
alert(admin.fullName); // Alice Cooper, setterì ìí´ ì¶ê°ë adminì íë¡í¼í°(name, surname)ìì ê°ì ê°ì ¸ì´
alert(user.fullName); // John Smith, 본ë userì ììë íë¡í¼í° ê°
íë¡í íì
userì getter í¨ì get fullNameì´ ì기 ë문ì (*)ë¡ íìí ì¤ìì get fullNameì´ í¸ì¶ëììµëë¤. ë§ì°¬ê°ì§ë¡ íë¡í íì
ì ì´ë¯¸ setter í¨ì(set fullName)ê° ì ìëì´ ì기 ë문ì (**)ë¡ íìí ì¤ì í ë¹ ì°ì°ì´ ì¤íëë©´ ê°ì²´ userì íë¡í¼í°ê° ì¶ê°ëëê² ìëë¼ íë¡í íì
ì ìë setter í¨ìê° í¸ì¶ë©ëë¤.
thisê° ëíë´ë ê²
ì ìì를 ë³´ë©´ "set fullName(value) 본문ì thisì ì´ë¤ ê°ì´ ë¤ì´ê°ì§?"ë¼ë ì문ì ê°ì§ ì ììµëë¤. "íë¡í¼í° this.nameê³¼ this.surnameì ê°ì ì°ë©´ ê·¸ ê°ì´ userì ì ì¥ë ê¹, ìëë©´ adminì ì ì¥ë ê¹?"ë¼ë ì문ë ì길 ì ìì£ .
ëµì ê°ë¨í©ëë¤. thisë íë¡í íì
ì ìí¥ì ë°ì§ ììµëë¤.
ë©ìë를 ê°ì²´ìì í¸ì¶íë íë¡í íì
ìì í¸ì¶íë ìê´ìì´ thisë ì¸ì ë . ìì ìë ê°ì²´ì
ëë¤.
admin.fullName=ì¼ë¡ setter í¨ì를 í¸ì¶í ë, thisë userê° ìë adminì´ ëì£ .
ê°ì²´ íë를 ë§ë¤ê³ ì¬ê¸°ì ë©ìë를 ë§ì´ 구íí´ ëì ë¤ì, ì¬ë¬ ê°ì²´ìì ì´ ì»¤ë¤ë ê°ì²´ë¥¼ ììë°ê² íë ê²½ì°ê° ë§ê¸° ë문ì ì´ë° í¹ì§ì ì ììëì ì¼ í©ëë¤. ììë°ì ë©ìë를 ì¬ì©íëë¼ë ê°ì²´ë íë¡í íì ì´ ìë ìì ì ìí를 ìì í©ëë¤.
ìì를 íµí´ ì¢ ë ììë´
ìë¤. âë©ìë ì ì¥ìâ ìí ì íë ê°ì²´ animalì rabbitì´ ììë°ê² í´ë³´ê² ìµëë¤.
rabbit.sleep()ì í¸ì¶íë©´ ê°ì²´ rabbitì isSleepingíë¡í¼í°ê° ì¶ê°ë©ëë¤.
// animalì ë¤ìí ë©ìëê° ììµëë¤.
let animal = {
walk() {
if (!this.isSleeping) {
alert(`ëë¬¼ì´ ê±¸ì´ê°ëë¤.`);
}
},
sleep() {
this.isSleeping = true;
}
};
let rabbit = {
name: "íì í ë¼",
__proto__: animal
};
// rabbitì ìë¡ì´ íë¡í¼í° isSleepingì ì¶ê°íê³ ê·¸ ê°ì trueë¡ ë³ê²½í©ëë¤.
rabbit.sleep();
alert(rabbit.isSleeping); // true
alert(animal.isSleeping); // undefined (íë¡í íì
ìë isSleepingì´ë¼ë íë¡í¼í°ê° ììµëë¤.)
ì ì½ë를 ì¤íí í, ê°ì²´ì ìí를 그림ì¼ë¡ ëíë´ë©´ ë¤ìê³¼ ê°ìµëë¤.
rabbit ë§ê³ ë bird, snake ë±ì´ animalì ììë°ëë¤ê³ í´ë´
ìë¤. ì´ ê°ì²´ë¤ë rabbitì²ë¼ animalì 구íë ë©ìë를 ì¬ì©í ì ììµëë¤. ì´ë ììë°ì ë©ìëì thisë animalì´ ìë ì¤ì ë©ìëê° í¸ì¶ëë ìì ì ì (.) ìì ìë ê°ì²´ê° ë©ëë¤. ë°ë¼ì thisì ë°ì´í°ë¥¼ ì°ë©´ animalì´ ìë í´ë¹ ê°ì²´ì ìíê° ë³íí©ëë¤.
ì´ë¥¼ íµí´ ì°ë¦¬ë ë©ìëë ê³µì ëì§ë§, ê°ì²´ì ìíë ê³µì ëì§ ìëë¤ê³ ê²°ë¡ ë´ë¦´ ì ììµëë¤.
forâ¦in ë°ë³µë¬¸
for..inì ìì íë¡í¼í°ë ìíëìì í¬í¨ìíµëë¤.
ìì:
let animal = {
eats: true
};
let rabbit = {
jumps: true,
__proto__: animal
};
// Object.keysë ê°ì²´ ìì ì í¤ë§ ë°íí©ëë¤.
alert(Object.keys(rabbit)); // jumps
// for..inì ê°ì²´ ìì ì í¤ì ìì íë¡í¼í°ì í¤ ëª¨ë를 ìíí©ëë¤.
for(let prop in rabbit) alert(prop); // jumps, eats
obj.hasOwnProperty(key)를 ì´ì©íë©´ ìì íë¡í¼í°ë¥¼ ìí ëììì ì ì¸í ì ììµëë¤. ì´ ë´ì¥ ë©ìëë keyì ëìíë íë¡í¼í°ê° ìì íë¡í¼í°ê° ìëê³ objì ì§ì 구íëì´ìë íë¡í¼í°ì¼ ëë§ true를 ë°íí©ëë¤.
obj.hasOwnProperty(key)를 ìì©íë©´ ìë ììììì²ë¼ ìì íë¡í¼í°ë¥¼ 걸ë¬ë¼ ì ìê³ , ìì íë¡í¼í°ë§ì ëìì¼ë¡ 무ì¸ê°ë¥¼ í ìë ììµëë¤.
let animal = {
eats: true
};
let rabbit = {
jumps: true,
__proto__: animal
};
for(let prop in rabbit) {
let isOwn = rabbit.hasOwnProperty(prop);
if (isOwn) {
alert(`ê°ì²´ ìì ì íë¡í¼í°: ${prop}`); // ê°ì²´ ìì ì íë¡í¼í°: jumps
} else {
alert(`ìì íë¡í¼í°: ${prop}`); // ìì íë¡í¼í°: eats
}
}
ì ììì ìì ê´ê³ë¥¼ 그림ì¼ë¡ ëíë´ë©´ ë¤ìê³¼ ê°ìµëë¤. rabbitì animalì, animalì Object.prototypeì, Object.prototypeì nullì ììë°ê³ ììµëë¤. ì°¸ê³ ë¡ animalì´ Object.prototype를 ììë°ë ì´ì ë animalì ê°ì²´ 리í°ë´ ë°©ìì¼ë¡ ì ì¸íì기 ë문ì
ëë¤.
그림ì ë³´ë©´ for..in ììì ì¬ì©í ë©ìë hasOwnPropertyê° Object.prototype.hasOwnPropertyìì ìë¤ë ê²ì íì¸í ì ììµëë¤.
ì? ê·¸ë°ë° ìì íë¡í¼í°ì¸ eatsë ì¼ë¿ ì°½ì ì¶ë ¥ëëë°, hasOwnPropertyë ì¶ë ¥ëì§ ìììµëë¤. ë¬´ì¨ ì¼ì´ ìë 걸ê¹ì?
ì´ì ë ê°ë¨í©ëë¤. hasOwnPropertyë ì´ê±° ê°ë¥í(enumerable) íë¡í¼í°ê° ìë기 ë문ì
ëë¤. Object.prototypeì ìë 모ë ë©ìëì enumerable íëê·¸ë falseì¸ë°, for..inì ì¤ì§ ì´ê±° ê°ë¥í íë¡í¼í°ë§ ìí ëìì í¬í¨í기 ë문ì hasOwnPropertyë ì¼ë¿ì°½ì ì¶ë ¥ëì§ ììµëë¤.
Object.keys, Object.values ê°ì´ ê°ì²´ì í¤-ê°ì ëìì¼ë¡ 무ì¸ê°ë¥¼ íë ë©ìë ëë¶ë¶ì ìì íë¡í¼í°ë¥¼ ì ì¸íê³ ëìí©ëë¤.
íë¡í íì ìì ììë°ì íë¡í¼í°ë ì ì¸íê³ , í´ë¹ ê°ì²´ìì ì ìí íë¡í¼í°ë§ ì°ì° ëìì í¬í¨í©ëë¤.
ìì½
- ìë°ì¤í¬ë¦½í¸ì 모ë ê°ì²´ì ì¨ê¹ íë¡í¼í°
[[Prototype]]ì´ ìëë°, ì´ íë¡í¼í°ë ê°ì²´ënullì ê°ë¦¬íµëë¤. obj.__proto__를 ì¬ì©íë©´ íë¡í íì ì ì ê·¼í ì ììµëë¤.__proto__ë[[Prototype]]ì getter·setterë¡ ì°ì´ëë°, ìì¦ì ì ì°ì§ ììµëë¤. ìì¸í ì¬íì ë¤ìª½ ì±í°ìì ë¤ë£° ìì ì ëë¤.[[Prototype]]ì´ ì°¸ì¡°íë ê°ì²´ë¥¼ 'íë¡í íì âì´ë¼ê³ í©ëë¤.- ê°ì²´ìì íë¡í¼í°ë¥¼ ì½ê±°ë ë©ìë를 í¸ì¶íë ¤ëë° í´ë¹íë íë¡í¼í°ë ë©ìëê° ìì¼ë©´ ìë°ì¤í¬ë¦½í¸ë íë¡í íì ìì íë¡í¼í°ë ë©ìë를 ì°¾ìµëë¤.
- ì ê·¼ì íë¡í¼í°ê° ìë ë°ì´í° íë¡í¼í°ë¥¼ ë¤ë£¨ê³ ìë¤ë©´, ì°ê¸°ë ì§ì°ê¸°ì ê´ë ¨ ì°ì°ì íë¡í íì ì íµíì§ ìê³ ê°ì²´ì ì§ì ì ì©ë©ëë¤.
- íë¡í íì
ìì ììë°ì
methodë¼ëobj.method()를 í¸ì¶íë©´methodììthisë í¸ì¶ ëì ê°ì²´ì¸obj를 ê°ë¦¬íµëë¤. for..inë°ë³µë¬¸ì ê°ì²´ ìì²´ìì ì ìí íë¡í¼í°ë¿ë§ ìëë¼ ìì íë¡í¼í°ë ìí ëìì í¬í¨í©ëë¤. ë°ë©´, í¤-ê°ê³¼ ê´ë ¨ë ë´ì¥ ë©ìë ëë¶ë¶ì ìì íë¡í¼í°ë ì ì¸íê³ ê°ì²´ ìì²´ íë¡í¼í°ë§ì ëìì¼ë¡ ëìí©ëë¤.
ëê¸
<code>í그를, ì¬ë¬ ì¤ë¡ 구ì±ë ì½ë를 ì½ì íê³ ì¶ë¤ë©´<pre>í그를 ì´ì©íì¸ì. 10ì¤ ì´ìì ì½ëë plnkr, JSBin, codepen ë±ì ìëë°ì¤ë¥¼ ì¬ì©íì¸ì.