JavaScriptë ëì íì ì´ê³ ì ì íì ì´ ì기 ë문ì, (Java ëë C++ì ê°ì) í´ëì¤ ê¸°ë° ì¸ì´ì ê²½íì´ ìë ê°ë°ììê²ë ì½ê° í¼ëì¤ë½ìµëë¤.
ììê³¼ ê´ë ¨íì¬, JavaScriptìë ê°ì²´ë¼ë íëì êµ¬ì¡°ë§ ììµëë¤. ê° ê°ì²´ìë íë¡í íì
ì´ë¼ë ë¤ë¥¸ ê°ì²´ì ëí ë§í¬ë¥¼ ë³´ì íë ë¹ê³µê° ìì±ì´ ììµëë¤. ê·¸ íë¡í íì
ê°ì²´ë ìì ë§ì íë¡í íì
ì ê°ì§ê³ ìì¼ë©°, íë¡í íì
ì¼ë¡ null
ì ê°ì§ ê°ì²´ì ëë¬í ëê¹ì§ ì´ ì°ê²°ì ê³ìë©ëë¤. ì ìì ë°ë¥´ë©´ null
ìë íë¡í íì
ì´ ìì¼ë©°, ì´ íë¡í íì
ì²´ì¸ìì ìµì¢
ë§í¬ ìí ì í©ëë¤. íë¡í íì
ì²´ì¸ì 모ë 구ì±ììë¤ì ë³ê²½íê±°ë ë°íì ì íë¡í íì
ì êµì²´í ìë ìì¼ë¯ë¡ JavaScriptìë ì ì ëì¤í¨ì¹(static dispatching)ê³¼ ê°ì ê°ë
ì´ ììµëë¤.
ì´ë¬í í¼ëì ì¢ ì¢ JavaScriptì ì½ì ì¤ íëë¡ ìê°ëì´ì§ì§ë§, íë¡í íì ìì ëª¨ë¸ ìì²´ë ì¬ì¤ ê³ ì ì ì¸ ëª¨ë¸ë³´ë¤ ë ê°ë ¥í©ëë¤. ì를 ë¤ì´, classesê° êµ¬íëë ë°©ìì¸ íë¡í íì ëª¨ë¸ ìì ê³ ì ì ì¸ ëª¨ë¸ì 구ì¶íë ê²ì ë§¤ì° ê°ë¨í©ëë¤.
í´ëì¤ë íì¬ ë리 ì±íëì´ JavaScriptì ìë¡ì´ í¨ë¬ë¤ìì´ ëìì§ë§, í´ëì¤ë ìë¡ì´ ìì í¨í´ì ê°ì ¸ì¤ì§ ììµëë¤. í´ëì¤ë ëë¶ë¶ì íë¡í íì ë©ì»¤ëì¦ì ì¶ìííì§ë§, ë´ë¶ìì íë¡í íì ì´ ìëíë ë°©ìì ì´í´íë ê²ì ì¬ì í ì ì©í©ëë¤.
íë¡í íì ì²´ì¸ì ì´ì©í ìì ìì± ììJavaScript ê°ì²´ë ìì±ì ì ì¥íë ëì ì¸ "ê°ë°©"ê³¼ (ì기ë§ì ìì±ì´ë¼ê³ ë¶ë¦ ëë¤) íë¡í íì ê°ì²´ì ëí ë§í¬ë¥¼ ê°ì§ëë¤. ê°ì²´ì ì´ë¤ ìì±ì ì ê·¼íë ¤í ë, ê·¸ ê°ì²´ ìì²´ ìì± ë¿ë§ ìëë¼ ê°ì²´ì íë¡í íì , ê·¸ íë¡í íì ì íë¡í íì ë± íë¡í íì ì²´ì¸ì ì¢ ë¨ì ì´ë¥¼ ëê¹ì§ ê·¸ ìì±ì íìí©ëë¤.
ì°¸ê³ : ECMAScript íì¤ì someObject.[[Prototype]]
ì ê°ì²´ someObject
ì íë¡í íì
ì ì§ìíëë¡ ëª
ìíììµëë¤. [[Prototype]]
ë´ë¶ ì¬ë¡¯ì ê°ê° Object.getPrototypeOf()
ê³¼ Object.setPrototypeOf()
í¨ìë¡ ì ê·¼íê³ ìì í ì ììµëë¤. ì´ê²ì JavaScriptì íì¤ì ìëë ë§ì ë¸ë¼ì°ì ì 구íëì´ ì¬ì¤ìì íì¤ì´ ë ìì± __proto__
ê³¼ ëì¼í©ëë¤. ê°ê²°í¨ì ì ì§íê³ í¼ëì ë°©ì§í기 ìí´ í기ë²ìì obj.__proto__
를 ì¬ì©íì§ ìê³ , obj.[[Prototype]]
ì ì¬ì©í©ëë¤. ì´ê²ì Object.getPrototypeOf(obj)
ì í´ë¹í©ëë¤.
ìì±ìë¡ ì¬ì©ë ë 주ì´ì§ í¨ìì ìí´ ìì±ë ê°ì²´ì 모ë ì¸ì¤í´ì¤
ì [[Prototype]]
ì´ í ë¹ëëë¡ ì§ì íë í¨ìì func.prototype
ìì±ê³¼ í¼ëí´ìë ì ë©ëë¤. ëì¤ ì¹ì
ìì ìì±ì í¨ìì prototype
ìì±ì ëí´ ë
¼ìí ê²ì
ëë¤.
ê°ì²´ì [[Prototype]]
ì ì§ì íë ë°©ë²ìë ì¬ë¬ ê°ì§ê° ìì¼ë©°, ëì¤ ì¹ì
ì ëì´ëì´ ììµëë¤. ì§ê¸ì, ì¤ëª
ì ìí´ __proto__
문ë²ì ì¬ì©í©ëë¤. { __proto__: ... }
êµ¬ë¬¸ì´ íì¤ì´ë©°, ë ì´ì ì¬ì©ëì§ ìë obj.__proto__
ì ê·¼ìì ë¤ë¥´ë¤ë ì ì ì°¸ê³ í´ì£¼ììì¤. { a: 1, b: 2, __proto__: c }
ì ê°ì ê°ì²´ 리í°ë´ìì, ê° c
(null
ëë ë¤ë¥¸ ê°ì²´ì¬ì¼ í©ëë¤)ë í´ë¹ ê°ì²´ì [[Prototype]]
ì´ ë©ëë¤. ë°ë©´, a
ë° b
ì ê°ì ë¤ë¥¸ í¤ë í´ë¹ ê°ì²´ì ìì²´ ìì±ì´ ë©ëë¤. [[Prototype]]
ì ê°ì²´ì "ë´ë¶ ìì±"ì¼ ë¿ì´ë¯ë¡, ì´ êµ¬ë¬¸ì ë§¤ì° ìì°ì¤ë½ê² ì½íë ë¶ë¶ì
ëë¤.
ë¤ìì ìì±ì ì ê·¼íë ¤ê³ í ë ë°ìíë ìí©ì ëë¤.
const o = {
a: 1,
b: 2,
// __proto__ë [[Prototype]]ì ì¤ì í©ëë¤.
// ì¬ê¸°ì ë¤ë¥¸ ê°ì²´ 리í°ë´ë¡ ì§ì ëì´ ììµëë¤.
__proto__: {
b: 3,
c: 4,
},
};
// o.[[Prototype]]ì ìì± 'b'ì 'c'를 ê°ì§ê³ ììµëë¤.
// o.[[Prototype]].[[Prototype]] ì Object.prototype ì
ëë¤(무ìì ì미íëì§ ëì¤ì ì¤ëª
íê² ìµëë¤).
// ë§ì§ë§ì¼ë¡, o.[[Prototype]].[[Prototype]].[[Prototype]]ì nullì
ëë¤.
// nullì íë¡í íì
ì ì¢
ë¨ì ë§íë©° ì ìì ìí´ì ì¶ê° [[Prototype]]ì ììµëë¤.
// ê·¸ë¬ë©´ ì ì²´ íë¡í íì
ì²´ì¸ì ë¤ìê³¼ ê°ìµëë¤.
// {a: 1, b: 2} ---> {b: 3, c: 4} ---> Object.prototype ---> null
console.log(o.a); // 1
// oì 'a' ìì²´ ìì ìì±ì´ ììµëê¹? ë¤, ê·¸ ê°ì 1ì
ëë¤.
console.log(o.b); // 2
// oì 'b'ë¼ë ìì²´ ìì ìì±ì´ ììµëê¹? ë¤, ê·¸ ê°ì 2ì
ëë¤.
// íë¡í íì
ìì 'b'ë¼ë ìì±ì ê°ì§ì§ë§ ì´ ê°ì ì°ì´ì§ ììµëë¤. ì´ê²ì "ìì±ì ê°ë ¤ì§(property shadowing)" ì´ë¼ê³ ë¶ë¦
ëë¤.
console.log(o.c); // 4
// oë 'c'ë¼ë ìì±ì ìì íëì? ìëì, íë¡í íì
ì íì¸í´ë³´ì.
// o.[[Prototype]]ì 'c'ë¼ë ìì±ì ìì íëì? ë¤, ê°ì 4ì´ë¤.
console.log(o.d); // undefined
// oì 'd' ìì²´ ìì±ì´ ììµëê¹? ìëì, íë¡í íì
ì íì¸íì¸ì.
// Is there a 'd' own property on o.[[Prototype]]? No, check its prototype.
// o.[[Prototype]]ì 'd' ìì²´ ìì ìì±ì´ ììµëê¹? ìëì, íë¡í íì
ì íì¸íì¸ì.
// o.[[Prototype]].[[Prototype]]ì Object.prototypeì´ê³ ,
// 기본ì ì¼ë¡ 'd' ìì±ì´ ììµëë¤. íë¡í íì
ì íì¸íì¸ì.
// o.[[Prototype]].[[Prototype]].[[Prototype]]ì null, ê²ìì ì¤ì§í©ëë¤,
// ìì±ì ì°¾ì ì ìì´ì, undefined를 ë°íí©ëë¤.
ê°ì²´ì ìì±ì ê°ì ì§ì íë©´ "ì기ë§ì ìì±"ì´ ìì±ë©ëë¤. ë¨, getter or setterê° ì ì©ëë ìì±ì´ ììëë ê²½ì° ìì¸ì ì¸ ê·ì¹ì´ ì ì©ë©ëë¤.
ë§ì°¬ê°ì§ë¡, ë 긴 íë¡í íì ì²´ì¸ì ë§ë¤ ì ìì¼ë©°, 모ë ì²´ì¸ìì ìì±ì ì°¾ì ì ììµëë¤.
const o = {
a: 1,
b: 2,
// __proto__ë [[Prototype]]ì ì¤ì í©ëë¤.
// ì¬ê¸°ì ë¤ë¥¸ ê°ì²´ 리í°ë´ë¡ ì§ì ëì´ ììµëë¤.
__proto__: {
b: 3,
c: 4,
__proto__: {
d: 5,
},
},
};
// { a: 1, b: 2 } ---> { b: 3, c: 4 } ---> { d: 5 } ---> Object.prototype ---> null
console.log(o.d); // 5
ë©ìë ìì
JavaScriptìë í´ëì¤ ê¸°ë° ì¸ì´ìì ì ìíë íìì "ë©ìë"ê° ììµëë¤. JavaScriptììë 모ë í¨ì를 ìì±ì ííë¡ ê°ì²´ì ì¶ê°í ì ììµëë¤. ììë í¨ìë ìì íìë "ìì±ì ê°ë ¤ì§"ì í¬í¨íì¬ ë¤ë¥¸ 모ë ìì±ì²ë¼ ìëí©ëë¤(ë¨, ììì ì¸ê¸í "ìì±ì ê°ë ¤ì§" ëì "ë©ìë ì¤ë²ë¼ì´ë©, method overriding" ë¼ë ì©ì´ë¥¼ ì¬ì©íë¤).
ììë í¨ìê° ì¤í ë ë, this
ê°ì í¨ìê° ìì²´ ìì±ì¸ íë¡í íì
ê°ì²´ê° ìëë¼ ìì ê°ì²´ë¥¼ ê°ë¦¬íµëë¤.
const parent = {
value: 2,
method() {
return this.value + 1;
},
};
console.log(parent.method()); // 3
// ì´ ê²½ì° parent.method를 í¸ì¶í ë, 'this'ë ë¶ëª¨ë¥¼ ê°ë¦¬íµëë¤.
// ììì ë¶ëª¨ë¡ë¶í° ììë°ë ê°ì²´ì
ëë¤.
const child = {
__proto__: parent,
};
console.log(child.method()); // 3
// child.methodê° í¸ì¶ëë©´, 'this'ë ììì ê°ë¦¬íµëë¤.
// ììì´ ë¶ëª¨ì ë©ìë를 ììë°ì ë,
// ìììì 'value' ìì±ì ì°¾ìµëë¤. ê·¸ë¬ë ììì 'value'ë¼ë ìì²´ ìì±ì´ ì기 ë문ì,
// í´ë¹ ìì±ì [[Prototype]]ìì ì°¾ì ì ìì¼ë©°, ì´ë parent.valueì
ëë¤.
child.value = 4; // ììì ìì± 'value'ì ê° 4를 í ë¹í©ëë¤.
// ì´ ì½ëë ë¶ëª¨ì 'value' ìì±ì ì¨ê¹ëë¤.
// ìì ê°ì²´ë ì´ì ë¤ìê³¼ ê°ìµëë¤.
// { value: 4, __proto__: { value: 2, method: [Function] } }
console.log(child.method()); // 5
// Since child now has the 'value' property, 'this.value' means
// ììì ì´ì 'value' ìì±ì ê°ì§ë¯ë¡ 'this.value'ë child.value를 ì미í©ëë¤.
ìì±ì
모ë ì¸ì¤í´ì¤ê° ëì¼í ëªê°ì§ ëì¼í ìì±ì ê³µì íë ê²½ì°, íë¡í íì
ì ê°ì ì´ ëë¬ë©ëë¤. ì´ë í¹í ë©ìë를 ê³µì í ê²½ì° ëì± ëëë¬ì§ëë¤. ìë¡, getValue
í¨ì를 íµí´ ì ê·¼í ì ìë ê°ì í¬í¨íë 'ìì' ê°ì²´ë¥¼ ì¬ë¿ ë§ëë ê²½ì°ë¥¼ ìê°í´ë´
ìë¤. ë¨ìí 구íì ë¤ìê³¼ ê°ìµëë¤.
const boxes = [
{ value: 1, getValue() { return this.value; } },
{ value: 2, getValue() { return this.value; } },
{ value: 3, getValue() { return this.value; } },
];
ê° ì¸ì¤í´ì¤ìë ì¤ë³µëê³ ë¶íìí ìì
ì ìííë ê³ ì í í¨ì ìì±ì´ ì기 ë문ì, 기ëì 미ì¹ì§ 못íë ì½ëê° ë©ëë¤. ëì ì, getValue
를 모ë ììì [[Prototype]]
ì¼ë¡ ì´ëí ì ììµëë¤.
const boxPrototype = {
getValue() {
return this.value;
},
};
const boxes = [
{ value: 1, __proto__: boxPrototype },
{ value: 2, __proto__: boxPrototype },
{ value: 3, __proto__: boxPrototype },
];
ì´ë ê² íë©´, 모ë ììì getValue
ë©ìëê° ëì¼í í¨ì를 참조íë¯ë¡, ë©ëª¨ë¦¬ì ì¬ì©ëì´ ì¤ì´ëëë¤. ê·¸ë¬ë 모ë ê°ì²´ ìì±ì ëí´ __proto__
를 ìëì¼ë¡ ë°ì¸ë©íë ê²ì ì¬ì í ë§¤ì° ë¶í¸í©ëë¤. ì´ê²ì ìì±ë 모ë ê°ì²´ì ëí´ [[Prototype]]
ì ìëì¼ë¡ ì¤ì íë constructor í¨ì를 ì¬ì©íë ê²½ì°ì
ëë¤. ìì±ìë new
ë¡ í¸ì¶ëë í¨ìì
ëë¤.
// ìì±ì í¨ì
function Box(value) {
this.value = value;
}
// Box() ìì±ììì ìì±ë 모ë ìì±
Box.prototype.getValue = function () {
return this.value;
};
const boxes = [new Box(1), new Box(2), new Box(3)];
new Box(1)
ì´ Box
ìì±ì í¨ììì ìì±ë "ì¸ì¤í´ì¤"ë¼ê³ ë§í ì ìëë°, Box.prototype
ì ì´ì ì ìì±í boxPrototype
ê°ì²´ì í¬ê² ë¤ë¥´ì§ ììµëë¤. Box.prototype
ì ê·¸ë¥ ì¼ë° ê°ì²´ì
ëë¤. ìì±ì í¨ììì ìì±ë 모ë ì¸ì¤í´ì¤ë ìëì¼ë¡ ìì±ìì prototype
ìì±ì [[Prototype]]
ì¼ë¡ ê°ê² ë©ëë¤. ì¦, Object.getPrototypeOf(new Box()) === Box.prototype
ì
ëë¤. 기본ì ì¼ë¡ Constructor.prototype
ìë ìì±ì í¨ì ì체를 참조íë constructor
ìì±ì´ íë ììµëë¤. ì¦, Box.prototype.constructor === Box
ì´ê¸° ë문ì, 모ë ì¸ì¤í´ì¤ìì ìë ìì±ìì ì ê·¼í ì ìê² ë©ëë¤.
ì°¸ê³ : ìì±ì í¨ììì ë°íë ê°ì´ ìì ê°ì´ ìëë¼ë©´, í´ë¹ ê°ì new
ííìì ê²°ê³¼ê° ë©ëë¤. ì´ ê²½ì°, [[Prototype]]
ì´ ì¬ë°ë¥´ê² ë°ì¸ë©ëì§ ìì ì ìì§ë§, ì¤ì ë¡ë ë§ì´ ë°ìíì§ ììµëë¤.
ì ìì±ì í¨ìë classesìì ë¤ìê³¼ ê°ì´ ë¤ì ìì±í ì ììµëë¤.
class Box {
constructor(value) {
this.value = value;
}
// ë©ìëë Box.prototypeì ìì±ë©ëë¤.
getValue() {
return this.value;
}
}
í´ëì¤ë ìì±ì í¨ìë³´ë¤ ë¬¸ë²ì ì¸ ì¤íì
ëë¤. ì¦, ì¬ì í Box.prototype
ì ì¡°ìíì¬ ëª¨ë ì¸ì¤í´ì¤ì ëìì ë³ê²½í ì ììµëë¤. ê·¸ë¬ë í´ëì¤ë 기본 íë¡í íì
ë©ì»¤ëì¦ì ëí ì¶ìíë¡ ì¤ê³ëì기 ë문ì, ì´ ììµìììë ë ê°ë²¼ì´ ìì±ì í¨ì 구문ì ì¬ì©íì¬ íë¡í íì
ì´ ìëíë ë°©ìì ë³´ê² ìµëë¤.
Box.prototype
ì 모ë ì¸ì¤í´ì¤ì [[Prototype]]
ê³¼ ëì¼í ê°ì²´ë¥¼ 참조í기 ë문ì, Box.prototype
ì ë³ê²½íì¬ ëª¨ë ì¸ì¤í´ì¤ì ëìì ë³ê²½í ì ììµëë¤.
function Box(value) {
this.value = value;
}
Box.prototype.getValue = function () {
return this.value;
};
const box = new Box(1);
// ì¸ì¤í´ì¤ê° ì´ë¯¸ ìì±ë í, `Box.prototype`ì ë³ê²½í©ëë¤.
Box.prototype.getValue = function () {
return this.value + 1;
};
box.getValue(); // 2
ê²°ê³¼ì ì¼ë¡, ì¬í ë¹ (Constructor.prototype
(Constructor.prototype = ...
))ì ë ê°ì§ ì´ì ë¡ ëì ìê°ì
ëë¤.
[[Prototype]]
ì ì´ì ì¬í ë¹ í ìì±ë ì¸ì¤í´ì¤ì [[Prototype]]
ê³¼ ë¤ë¥¸ ê°ì²´ë¥¼ 참조í©ëë¤. íëì [[Prototype]]
ì ë³ê²½í´ë ë ì´ì ë¤ë¥¸ ê°ì²´ê° ë³ê²½ëì§ ììµëë¤.constructor
ìì±ì ìëì¼ë¡ ì¬ì¤ì íì§ ìë í, instance.contructor
ìì ë ì´ì ìì±ì í¨ì를 ì¶ì í ì ìì´ ëì ë°©ìì ììí기 ì´ë ¤ìì§ëë¤. ì¼ë¶ 기본 ì ê³µ ì°ì°ì constructor
ìì±ë ì½ì¼ë©° ì¤ì ëì§ ìì ê²½ì°, ììëë¡ ìëíì§ ìì ì ììµëë¤.Constructor.prototype
ì ì¸ì¤í´ì¤ë¥¼ 구ì±í ëë§ ì ì©í©ëë¤. ì´ë Function.prototype
ìì±ì í¨ìì ìì²´ ìì ì íë¡í íì
ì¸ Constructor.[[Prototype]]
ê³¼ ì무 ê´ë ¨ì´ ììµëë¤. ì¦, Object.getPrototypeOf(Constructor) === Function.prototype
ì
ëë¤.
JavaScriptì ì¼ë¶ 리í°ë´ 구문ì ììì ì¼ë¡ [[Prototype]]
ì ì¤ì íë ì¸ì¤í´ì¤ë¥¼ ìì±í©ëë¤. ì를 ë¤ì´,
// ê°ì²´ 리í°ë´ (`__proto__` í¤ ìì)ì ìëì¼ë¡ `[[Prototype]]`ì¼ë¡ `Object.prototype`ì ê°ìµëë¤.
const object = { a: 1 };
Object.getPrototypeOf(object) === Object.prototype; // true
// ë°°ì´ ë¦¬í°ë´ì ìëì¼ë¡ `Array.prototype`ì `[[Prototype]]`ì¼ë¡ ê°ìµëë¤.
const array = [1, 2, 3];
Object.getPrototypeOf(array) === Array.prototype; // true
// RegExp 리í°ë´ì ìëì¼ë¡ `RegExp.prototype`ì `[[Prototype]]`ì¼ë¡ ê°ìµëë¤.
const regexp = /abc/;
Object.getPrototypeOf(regexp) === RegExp.prototype; // true
ìì±ì íí를 íµí´, "ë¬¸ë² ì¤íì ì ê±°"í ì ììµëë¤.
const array = new Array(1, 2, 3);
const regexp = new RegExp("abc");
ì를 ë¤ì´, map()
ê³¼ ê°ì "ë°°ì´ ë©ìë"ë ë¨ìí Array.prototype
ì ì ìë ë©ìëì
ëë¤. 모ë ë°°ì´ ì¸ì¤í´ì¤ìì ìëì¼ë¡ ì¬ì©í ì ììµëë¤.
ê²½ê³ : ë리 ìë ¤ì§ í ê°ì§ ì못ë 기ë¥ì´ ììµëë¤. ë°ë¡ Object.prototype
ëë ë¤ë¥¸ ë´ì¥ íë¡í íì
ì¤ íë를 íì¥íë ê²ì
ëë¤. ì´ ì못ë 기ë¥ì ìë Array.prototype.myMethod = function () {...}
를 ì ìí ë¤ì 모ë ë°°ì´ ì¸ì¤í´ì¤ìì myMethod
를 ì¬ì©íë ê²ì
ëë¤.
ì´ë¬í ì못ë 기ë¥ì ììì´ í¨ì¹(monkey patching)ì´ë¼ê³ í©ëë¤. ììì´ í¨ì¹ì íê² ëë©´, ìì í¸íì±ì 문ì ê° ë°ìí©ëë¤. ì¸ì´ê° ëì¤ì ì´ ë©ìë를 ì¶ê°íì§ë§ ë¤ë¥¸ ìëª ì ì¬ì©íë©´, ì½ëê° ê¹¨ì§ ì ì기 ë문ì ëë¤. ì´ë¡ ì¸í´, SmooshGateì ê°ì ì¬ê³ ê° ë°ìíì¼ë©°, JavaScriptë "ì¹ì ì¤ë¨íì§ ìì¼ë ¤" ìëíë¯ë¡ ì¸ì´ê° ë°ì íë ë° ìì´ í° ì¥ì ë¬¼ì´ ë ì ììµëë¤.
ë´ì¥ ì ê³µ íë¡í íì
ì íì¥í´ë ì¢ì ì ì¼í
ê²½ì°ë ìµì JavaScript ìì§ì 기ë¥ì ì´ì ë²ì ììë ì¬ì©í ì ìê² í´ì¤ ëì
ëë¤(backport). ìë¡,Array.prototype.forEach
ê° ììµëë¤.
í¥ë¯¸ë¡ê²ë, ì¼ë¶ ë´ì¥ ìì±ìì prototype
ìì±ì ìì¬ì ì¸ ì´ì ë¡ í´ë¹ ì¸ì¤í´ì¤ ìì²´ì
ëë¤. ì를 ë¤ì´, Number.prototype
ì ì«ì 0ì´ê³ , Array.prototype
ì ë¹ ë°°ì´ì´ê³ , RegExp.prototype
ì /(?:)/
ì
ëë¤.
Number.prototype + 1; // 1
Array.prototype.map((x) => x + 1); // []
String.prototype + "a"; // "a"
RegExp.prototype.source; // "(?:)"
Function.prototype(); // Function.prototypeì ìì²´ë¡ íë¡ê·¸ë¨ì ì무 ìì
ë ìííì§ ë§ë¼ê³ ì§ìíë (no-operation, no-op) í¨ìì
ëë¤.
ê·¸ë¬ë, ì´ê²ì ì¬ì©ì ì ì ìì±ìë Map
ê³¼ ê°ì ìµì ìì±ìì ê²½ì°ìë í´ë¹ëì§ ììµëë¤.
Map.prototype.get(1);
// Uncaught TypeError: í¸íëì§ ìë Map.prototypeìì í¸ì¶ë get ë©ìë
ë 긴 ìì ì²´ì¸ êµ¬ì¶
Constructor.prototype
ìì±ì Constructor.prototype
ì ìì²´ [[Prototype]]
ì í¬í¨íì¬, ìì±ì ì¸ì¤í´ì¤ì [[Prototype]]
ì´ ë©ëë¤. 기본ì ì¼ë¡ Constructor.prototype
ì ì¼ë° ê°ì²´ì
ëë¤. ì¦, Object.getPrototypeOf(Constructor.prototype) === Object.prototype
ì
ëë¤. ì ì¼í ìì¸ë Object.prototype
ìì²´ì´ë©°, [[Prototype]]
ì null
ì
ëë¤. ì¦, Object.getPrototypeOf(Object.prototype) === null
ì
ëë¤. ë°ë¼ì, ì¼ë°ì ì¸ ìì±ìë ë¤ì íë¡í íì
ì²´ì¸ì ë¹ëí©ëë¤.
function Constructor() {}
const obj = new Constructor();
// obj ---> Constructor.prototype ---> Object.prototype ---> null
ë 긴 íë¡í íì
ì²´ì¸ì 구ì¶íë ¤ë©´, Object.setPrototypeOf()
í¨ì를 íµí´ Constructor.prototype
ì [[Prototype]]
ì ì¤ì í ì ììµëë¤.
function Base() {}
function Derived() {}
// `Derived.prototype`ì `[[Prototype]]`ì `Base.prototype`ì¼ë¡ ì¤ì í©ëë¤.
Object.setPrototypeOf(Derived.prototype, Base.prototype);
const obj = new Derived();
// obj ---> Derived.prototype ---> Base.prototype ---> Object.prototype ---> null
í´ëì¤ ë¬¸ë² ì©ì´ë¡, ì´ë extends
구문ì ì¬ì©íë ê²ê³¼ ëì¼í©ëë¤.
class Base {}
class Derived extends Base {}
const obj = new Derived();
// obj ---> Derived.prototype ---> Base.prototype ---> Object.prototype ---> null
ìì ì²´ì¸ì 구ì¶í기 ìí´, Object.create()
를 ì¬ì©íë ì¼ë¶ ë ê±°ì ì½ë를 ë³¼ ìë ììµëë¤. ê·¸ë¬ë ì´ê²ì prototype
ìì±ì ì¬í ë¹íê³ constructor
ìì±ì ì ê±°í기 ë문ì, ì¤ë¥ê° ë ë§ì´ ë°ìí ì ììµëë¤. ìì±ìê° ìì§ ì¸ì¤í´ì¤ë¥¼ ìì±íì§ ìì ê²½ì°ìë ì±ë¥ìì ì»ë ì´ì ëí ì²´ê°í기 ì´ë µìµëë¤.
function Base() {}
function Derived() {}
// `[[Prototype]]`ì¼ë¡ `Base.prototype`ì ì¬ì©íì¬ `Derived.prototypeì ìë¡ì´ ê°ì²´ì ë¤ì í ë¹í©ëë¤.
// ì´ë ê² íì§ ë§ì¸ì, ëì `Object.setPrototypeOf`를 ì¬ì©íì¬ ë³ê²½íì¸ì.
Derived.prototype = Object.create(Base.prototype);
íë¡í íì
ì¬ì¸µ ë¶ì
ë¤ìì ì´ë í ì¼ì´ ì¼ì´ëëì§ ì¢ ë ìì¸í ì´í´ë³´ê² ìµëë¤.
ììì ì¸ê¸í ê²ì²ë¼, JavaScriptìì í¨ìë ìì±ì ê°ì§ ì ììµëë¤. 모ë í¨ììë prototype
ì´ë¼ë í¹ìí ìì±ì´ ììµëë¤. ìëì ìì ì½ëë ë
립ì ì´ë¼ë ê²ì ì ìíì¸ì(ìëì ì½ë ì´ì¸ìë ì¹íì´ì§ì ë¤ë¥¸ JavaScriptê° ìë¤ê³ ê°ì í´ë 문ì ììµëë¤).
ìµì ì ì¤ìµì ìí´, ì½ìì ì´ê³ "console" íì¼ë¡ ì´ëíì¬ ìëì JavaScript ì½ë를 ë³µì¬íì¬ ë¶ì¬ë£ê³ , ìí°/Return í¤ë¥¼ ëë¬ì ì¤ííë ê²ì´ ì¢ìµëë¤(ì½ìì ëë¶ë¶ ì¹ ë¸ë¼ì°ì ì ê°ë°ì ë구ì í¬í¨ëì´ ììµëë¤. ìì¸í ë´ì©ì Firefox Developer Tools, Chrome DevTools ë° Edge DevToolsì ì°¸ê³ íì¸ì).
function doSomething() {}
console.log(doSomething.prototype);
// í¨ì ì ì¸ ë°©ë²ì ì¤ìíì§ ììµëë¤. JavaScriptì í¨ìë íì 기본 íë¡í íì
ìì±ì ê°ìµëë¤.
// í ê°ì§ ìì¸ê° ììµëë¤. íì´í í¨ììë 기본 íë¡í íì
ìì±ì´ ììµëë¤.
const doSomethingFromArrowFunction = () => {};
console.log(doSomethingFromArrowFunction.prototype);
ì ë´ì©ì í ëë¡, ì½ìì ë³´ë©´ doSomething()
ì 기본 prototype
ìì±ì ê°ì§ê³ ììµëë¤. ì½ë를 ì¤íí ë¤ì ì½ìììë ë¤ìê³¼ ì ì¬í ííì ê°ì²´ê° íìëì´ì¼ í©ëë¤.
{ constructor: Æ doSomething(), [[Prototype]]: { constructor: Æ Object(), hasOwnProperty: Æ hasOwnProperty(), isPrototypeOf: Æ isPrototypeOf(), propertyIsEnumerable: Æ propertyIsEnumerable(), toLocaleString: Æ toLocaleString(), toString: Æ toString(), valueOf: Æ valueOf() } }
ì°¸ê³ : Chrome ì½ìì [[Prototype]]
ì ì¬ì©íì¬, ëª
ì¸ì ì©ì´ì ë°ë¼ ê°ì²´ì íë¡í íì
ì ëíë
ëë¤. Firefoxë <prototype>
ì ì¬ì©íëë°, ì¼ê´ì±ì ìí´ [[Prototype]]
ì ì¬ì©í©ëë¤.
ìëì ê°ì´, doSomething()
ì íë¡í íì
ì ìì±ì ì¶ê°í ì ììµëë¤.
function doSomething() {}
doSomething.prototype.foo = "bar";
console.log(doSomething.prototype);
ê²°ê³¼:
{ foo: "bar", constructor: Æ doSomething(), [[Prototype]]: { constructor: Æ Object(), hasOwnProperty: Æ hasOwnProperty(), isPrototypeOf: Æ isPrototypeOf(), propertyIsEnumerable: Æ propertyIsEnumerable(), toLocaleString: Æ toLocaleString(), toString: Æ toString(), valueOf: Æ valueOf() } }
ì´ì new
ì°ì°ì를 ì¬ì©í´ì íë¡í íì
기ë°ì doSomething()
ì¸ì¤í´ì¤ë¥¼ ìì±í ì ììµëë¤. new ì°ì°ì를 ì¬ì©íë ¤ë©´ new
ì ëì´ë¥¼ ì ì¸íê³ ì¼ë°ì ì¼ë¡ í¨ì를 í¸ì¶íì¸ì. new
ì°ì°ìë¡ í¨ì를 í¸ì¶íë©´ í´ë¹ í¨ìì ì¸ì¤í´ì¤ ê°ì²´ë¥¼ ë°íë°ìµëë¤. ê·¸ë¬ë©´ ìì±ë¤ì ì´ ê°ì²´ì ì¶ê°í ì ììµëë¤.
ë¤ìì ì½ë를 ì¤íí´ë´ ìë¤.
function doSomething() {}
doSomething.prototype.foo = "bar"; // íë¡í íì
ì ìì± ì¶ê°
const doSomeInstancing = new doSomething();
doSomeInstancing.prop = "some value"; // ê°ì²´ì ìì± ì¶ê°
console.log(doSomeInstancing);
ì¤íí íìë ê²°ê³¼ë ìëì ë¹ì·í ê²ëë¤.
{ prop: "some value", [[Prototype]]: { foo: "bar", constructor: Æ doSomething(), [[Prototype]]: { constructor: Æ Object(), hasOwnProperty: Æ hasOwnProperty(), isPrototypeOf: Æ isPrototypeOf(), propertyIsEnumerable: Æ propertyIsEnumerable(), toLocaleString: Æ toLocaleString(), toString: Æ toString(), valueOf: Æ valueOf() } } }
ììì ë³¼ ì ìë¯ì´, doSomeInstancing
ì [[Prototype]]
ì doSomething.prototype
ì
ëë¤. ê·¸ë¬ë ì´ê²ì ì´ë¤ ìí ì íëì? doSomeInstancing
ì ìì±ì ì ê·¼íë©´ ë°íìì 먼ì doSomeInstancing
ì í´ë¹ ìì±ì´ ìëì§ íì¸í©ëë¤.
doSomeInstancing
ì ìì±ì´ ìì¼ë©´, ë°íìì doSomeInstancing.[[Prototype]]
(doSomething.prototype
)ìì ìì±ì ì°¾ìµëë¤. doSomeInstancing.[[Prototype]]
ì ì°¾ê³ ìë ìì±ì´ ìì¼ë©´ doSomeInstancing.[[Prototype]]
ì í´ë¹ ìì±ì´ ì¬ì©ë©ëë¤.
ê·¸ë ì§ ìê³ , doSomeInstancing.[[Prototype]]
ì ìì±ì´ ìì¼ë©´, doSomeInstancing.[[Prototype]].[[Prototype]]
ìì ìì±ì íì¸í©ëë¤. 기본ì ì¼ë¡, í¨ìì prototype
ìì± ì¤ [[Prototype]]
ì Object.prototype
ì
ëë¤. ë°ë¼ì, doSomeInstancing.[[Prototype]].[[Prototype]]
(doSomething.prototype.[[Prototype]]
(Object.prototype
)) ì ê²ì ì¤ì¸ ìì±ì ì°¾ìµëë¤.
ìì±ì´ doSomeInstancing.[[Prototype]].[[Prototype]]
ì ìì¼ë©´, doSomeInstancing.[[Prototype]].[[Prototype]].[[Prototype]]
ì íµí´ ì°¾ìµëë¤. ê·¸ë¬ë, doSomeInstancing.[[Prototype]].[[Prototype]].[[Prototype]]
ì´ ì¡´ì¬íì§ ìë 문ì ê° ìëë°, ê·¸ ì´ì ë Object.prototype.[[Prototype]]
ì´ null
ì´ê¸° ë문ì
ëë¤. ê·¸ë° ë¤ì, [[Prototype]]
ì ì ì²´ íë¡í íì
ì²´ì¸ì ì´í´ë³¸ í, ë°íìì ìì±ì´ ì¡´ì¬íì§ ìëë¤ê³ 주ì¥íê³ ìì±ì ê°ì´ undefined
ì´ë¼ê³ ê²°ì í©ëë¤.
ì½ìì ì½ë를 ì¶ê°ë¡ ì ë ¥í´ ë´ ìë¤.
function doSomething() {}
doSomething.prototype.foo = "bar";
const doSomeInstancing = new doSomething();
doSomeInstancing.prop = "some value";
console.log("doSomeInstancing.prop: ", doSomeInstancing.prop);
console.log("doSomeInstancing.foo: ", doSomeInstancing.foo);
console.log("doSomething.prop: ", doSomething.prop);
console.log("doSomething.foo: ", doSomething.foo);
console.log("doSomething.prototype.prop:", doSomething.prototype.prop);
console.log("doSomething.prototype.foo: ", doSomething.prototype.foo);
ì½ëì ê²°ê³¼ë ìëì ê°ìµëë¤.
doSomeInstancing.prop: some value doSomeInstancing.foo: bar doSomething.prop: undefined doSomething.foo: undefined doSomething.prototype.prop: undefined doSomething.prototype.foo: baríë¡í íì ì²´ì¸ì ë§ë¤ê³ ë³ê²½íë ë¤ìí ë°©ë²
ê°ì²´ë¥¼ ìì±íê³ íë¡í íì ì²´ì¸ì ë³ê²½íë ë¤ìí ë°©ë²ì ë§ëë³´ììµëë¤. ê° ì ê·¼ ë°©ìì ì¥ë¨ì ì ë¹êµíì¬, ë¤ìí ë°©ìì ì²´ê³ì ì¼ë¡ ìì½í©ëë¤.
ë¬¸ë² ìì±ìë¡ ê°ì²´ ìì±const o = { a: 1 };
// ìë¡ê² ë§ë¤ì´ì§ ê°ì²´ oë Object.prototypeì [[Prototype]]ì¼ë¡ ê°ì§ê³ ììµëë¤.
// Object.prototypeì íë¡í íì
ì null ì
ëë¤.
// o ---> Object.prototype ---> null
const b = ["yo", "whadup", "?"];
// Array.prototypeì ììë°ì ë°°ì´ë ë§ì°¬ê°ì§ ì
ëë¤.
// (ì´ë²ìë indexOf, forEach ë±ì ë©ìë를 ê°ì§ëë¤)
// íë¡í íì
ì²´ì¸ì ë¤ìê³¼ ê°ìµëë¤.
// b ---> Array.prototype ---> Object.prototype ---> null
function f() {
return 2;
}
// í¨ìë Function.prototype ì ììë°ìµëë¤.
// (ì´ íë¡í íì
ì call, bind ê°ì ë©ìë를 ê°ì§ëë¤).
// f ---> Function.prototype ---> Object.prototype ---> null
const p = { b: 2, __proto__: o };
// ìë¡ ìì±ë ê°ì²´ì [[Prototype]]ì´ __proto__ 리í°ë´ ìì±ì íµí´ ë¤ë¥¸ ê°ì²´ë¥¼ ê°ë¦¬í¤ëë¡ í ì ììµëë¤.
// (Object.prototype.__proto__ ì ê·¼ìì í¼ëíì§ ë§ì¸ì).
// p ---> o ---> Object.prototype ---> null
ê°ì²´ ì´ê¸°ììì __proto__
í¤ ì¬ì©ì ì¥ì ê³¼ ë¨ì ì¥ì 모ë ìµì ìì§ìì ì§ìë©ëë¤. ê°ì²´ê° ìë ê²ì __proto__
í¤ë¡ ì§ì íë©´ ìì¸ë¥¼ ë°ììí¤ì§ ìê³ ì¡°ì©í ì¤í¨í©ëë¤. Object.prototype.__proto__
ì¤ì ìì ë°ëë¡, ê°ì²´ 리í°ë´ ì´ê¸°ìì __proto__
ê° íì¤íëê³ ìµì íëìì¼ë©° Object.create
ë³´ë¤ ì±ë¥ì´ ë ë°ì´ë ì ììµëë¤. ê°ì²´ ìì± ì ì¶ê° ìì²´ ìì±ì ì ì¸íë ê²ì´ Object.create
ë³´ë¤ í¸ë¦¬í©ëë¤. ë¨ì IE10 ì´íììë ì§ìíì§ ììµëë¤. ì°¨ì´ì ì 모르ë ì¬ëë¤ì´ Object.prototype.__proto__
ì í¼ëí기 ì½ìµëë¤. ìì±ì í¨ì를 ì´ì©
JavaScriptìì ìì±ìë ë¨ì§ new ì°ì°ì를 ì¬ì©í´ í¨ì를 í¸ì¶íë©´ ëë¤.
function Graph() {
this.vertices = [];
this.edges = [];
}
Graph.prototype.addVertex = function (v) {
this.vertices.push(v);
};
const g = new Graph();
// gë ìì²´ ìì±ì¼ë¡ 'vertices' ì 'edges'를 ê°ì§ë ê°ì²´ì´ë¤.
// g.[[Prototype]]ì new Graph()ê° ì¤íë ë Graph.prototypeì ê°ì´ ë©ëë¤.
ìì±ì í¨ì ì¬ì©ì ì¥ì ê³¼ ë¨ì ì¥ì 모ë ìì§ìì ì§ìí©ëë¤(IE 5.5ê¹ì§ë ì§ì). ëí, ë§¤ì° ë¹ ë¥´ê³ , íì¤ì ë°ë¥´ê³ , JIT ìµì íê° ê°ë¥í©ëë¤. ë¨ì
ë ë¤ ì¤ì ë¡ë ì¼ë°ì ì¼ë¡ 문ì ê° ëì§ ììµëë¤.
Object.create ì´ì©Object.create()
ì í¸ì¶íë©´ ìë¡ì´ ê°ì²´ê° ìì±ë©ëë¤. ì´ ê°ì²´ì [[Prototype]]
ì í¨ìì 첫 ë²ì§¸ ì¸ìì
ëë¤.
const a = { a: 1 };
// a ---> Object.prototype ---> null
const b = Object.create(a);
// b ---> a ---> Object.prototype ---> null
console.log(b.a); // 1 (inherited)
const c = Object.create(b);
// c ---> b ---> a ---> Object.prototype ---> null
const d = Object.create(null);
// d ---> null (dë íë¡í íì
ì¼ë¡ ì§ì nullì ê°ë ê°ì²´ì
ëë¤)
console.log(d.hasOwnProperty);
// undefined, dë Object.prototypeìì ììë°ì§ ì기 ë문ì
ëë¤.
Object.create
ì ì¥ì ê³¼ ë¨ì ì¥ì 모ë ìµì ìì§ì ì§ìí©ëë¤. ìì± ì ê°ì²´ì [[Prototype]]
ì ì§ì ì¤ì í ì ìì¼ë¯ë¡, ë°íììì ê°ì²´ë¥¼ ëì± ìµì íí ì ììµëë¤. ëí Object.create(null)
를 ì¬ì©íì¬ íë¡í íì
ìì´ ê°ì²´ë¥¼ ìì±í ì ììµëë¤. ë¨ì IE8 ì´íììë ì§ìíì§ ììµëë¤. ê·¸ë¬ë Microsoftë IE8 ì´í를 ì¤ííë ìì¤í
ì ëí íì¥ ì§ìì ì¤ë¨í기 ë문ì ëë¶ë¶ì ìì© íë¡ê·¸ë¨ììë 문ì ê° ëì§ ììµëë¤. ëí, ë ë²ì§¸ ì¸ì를 ì¬ì©íë ê²½ì° ë린 ê°ì²´ ì´ê¸°íë¡ ì¸í´ ì±ë¥ì´ ì íë ì ììµëë¤. ê° ê°ì²´ ì¤ëª
ì ìì±ìë ìì²´ì ì¼ë¡ 구ë¶ë ì¤ëª
ì ê°ì²´ê° ì기 ë문ì
ëë¤. ê°ì²´ íí를 ê°ì§ë ììë§ ê°ì ê°ì²´ ì¤ëª
ì를 ì²ë¦¬í ë, ì§ì° ìê°ì´ ì¬ê°í 문ì ê° ë ì ììµëë¤. class를 ì´ì©íë ë°©ë²
class Rectangle {
constructor(height, width) {
this.name = "Rectangle";
this.height = height;
this.width = width;
}
}
class FilledRectangle extends Rectangle {
constructor(height, width, color) {
super(height, width);
this.name = "Filled rectangle";
this.color = color;
}
}
const filledRectangle = new FilledRectangle(5, 10, "blue");
// filledRectangle ---> FilledRectangle.prototype ---> Rectangle.prototype ---> Object.prototype ---> null
í´ëì¤ì ì¥ì ê³¼ ë¨ì ì¥ì 모ë ìµì ìì§ìì ì§ìë©ëë¤. ë§¤ì° ëì ê°ë
ì±ê³¼ ì ì§ ë³´ìì±. ë¹ê³µê° ìì±ì íë¡í íì
ìììì ììí ëì²´ê° ìë 기ë¥ì
ëë¤. ë¨ì í¹í ë¹ê³µê° ìì±ì´ ìë í´ëì¤ë 기존 í´ëì¤ë³´ë¤ ë ìµì íëì´ ììµëë¤(ìì§ êµ¬íìê° ì´ë¥¼ ê°ì í기 ìí´ ë
¸ë ¥íê³ ììµëë¤). ì´ì íê²½ììë ì§ìëì§ ìì¼ë©° ì¼ë°ì ì¼ë¡ ì¤ì ìë¹ì¤ì ì´ì íê²½ìì í´ëì¤ë¥¼ ì¬ì©íë ¤ë©´ í¸ëì¤íì¼ë¬(transpilers)ê° íìí©ëë¤. Object.setPrototypeOf()를 ì´ì©íë ë°©ë²
ìì 모ë ë©ìëë ê°ì²´ ìì± ì íë¡í íì
ì²´ì¸ì ì¤ì íì§ë§, Object.setPrototypeOf()
ë ì´ë¯¸ ìì±ë ê°ì²´ì ë´ë¶ [[Prototype]]
ìì±ì ë³ê²½í ì ììµëë¤.
const obj = { a: 1 };
const anotherObj = { b: 2 };
Object.setPrototypeOf(obj, anotherObj);
// obj ---> anotherObj ---> Object.prototype ---> null
Object.setPrototypeOf
ì ì¥ì ê³¼ ë¨ì ì¥ì 모ë ìµì ìì§ìì ì§ìë©ëë¤. ê°ì²´ì íë¡í íì
ì ëì ì¼ë¡ ì¡°ìí ì ìì¼ë©° Object.create(null)
ë¡ ë§ë íë¡í íì
ì´ ìë ê°ì²´ì íë¡í íì
ì ì ì©í ì ììµëë¤. ë¨ì ì±ë¥ì´ ì¢ì§ ììµëë¤. ê°ì²´ ìì± ì íë¡í íì
ì ì¤ì í ì ìë ê²½ì° í¼í´ì¼ í©ëë¤. ë§ì ìì§ë¤ì´ íë¡í íì
ì ìµì ííê³ ë¯¸ë¦¬ ì¸ì¤í´ì¤ë¥¼ í¸ì¶í ë ë©ëª¨ë¦¬ìì ë©ìëì ìì¹ë¥¼ ì¶ì¸¡íë ¤ê³ í©ëë¤. ê·¸ë¬ë íë¡í íì
ì ëì ì¼ë¡ ì¤ì íë©´ ì´ë¬í 모ë ìµì íê° ì¤ë¨ë©ëë¤. ëª
ì¸ì ë°ë¼ ìëíëë¡, ì¼ë¶ ìì§ì´ ìµì í í´ì 를 ìí´ ì½ë를 ë¤ì ì»´íì¼íê² í ì ììµëë¤. IE8 ì´íììë ì§ìíì§ ììµëë¤. __proto__ ì ê·¼ì를 ì¬ì©íë ë°©ë²
모ë ê°ì²´ë Object.prototype.__proto__
ì¤ì ì를 ììíë©°, ì´ë 기존 ê°ì²´ì [[Prototype]]
ì ì¤ì íë ë° ì¬ì©í ì ììµëë¤(__proto__
í¤ê° ê°ì²´ìì ì¬ì ìëì§ ìì ê²½ì°).
ê²½ê³ :
Object.prototype.__proto__
ì ê·¼ìë ë¹íì¤ì´ë©° ë ì´ì ì¬ì©ëì§ ììµëë¤. ëì ê±°ì íìObject.setPrototypeOf
를 ì¬ì©í´ì¼ í©ëë¤.
const obj = {};
// ì´ê²ì ì¬ì©íì§ ë§ì¸ì. ì¤ì§ ììì¼ ë¿ì
ëë¤.
obj.__proto__ = { barProp: "bar val" };
obj.__proto__.__proto__ = { fooProp: "foo val" };
console.log(obj.fooProp);
console.log(obj.barProp);
__proto__
ìì± ì¤ì ì ì¥ì ê³¼ ë¨ì ì¥ì 모ë ìµì ìì§ìì ì§ìë©ëë¤. __proto__
를 ê°ì²´ê° ìë ê²ì¼ë¡ ì¤ì íë©´ ì¡°ì©í ì¤í¨í©ëë¤. ìì¸ë¥¼ ëì§ì§ ììµëë¤. ë¨ì ì±ë¥ì´ ë¨ì´ì§ê³ ë ì´ì ì¬ì©ëì§ ììµëë¤. ë§ì ìì§ì´ íë¡í íì
ì ìµì ííê³ ë¯¸ë¦¬ ì¸ì¤í´ì¤ë¥¼ í¸ì¶í ë ë©ëª¨ë¦¬ìì ë©ìëì ìì¹ë¥¼ ì¶ì¸¡íë ¤ê³ í©ëë¤. ê·¸ë¬ë íë¡í íì
ì ëì ì¼ë¡ ì¤ì íë©´ ì´ë¬í 모ë ìµì íê° ì¤ë¨ëê³ ì¼ë¶ ìì§ì´ ëª
ì¸ì ë°ë¼ ìëíëë¡ ì½ëì ìµì í í´ì 를 ìí´ ë¤ì ì»´íì¼íëë¡ ê°ì í ì ììµëë¤. IE10 ì´íììë ì§ìíì§ ììµëë¤. __proto__
ì¤ì ìë íì¤ ì í ì¬íì´ë¯ë¡, 모ë íë«í¼ìì ìëíì§ ìì ì ììµëë¤. ëì ê±°ì íì Object.setPrototypeOf
를 ì¬ì©í´ì¼ í©ëë¤. ì±ë¥
íë¡í íì ì²´ì¸ìì ììì ìë ìì±ì ëí ì¡°í ìê°ì ì±ë¥ì ë¶ì ì ì¸ ìí¥ì ë¯¸ì¹ ì ìì¼ë©°, ì´ë ì±ë¥ ì¤ì¬ì ì½ëìì ì¬ê°í 문ì ì ëë¤. ëí, ì¡´ì¬íì§ë ìë ìì±ì ì ê·¼íë ¤ë ìëë íì 모ë íë¡í íì ì²´ì¸ì¸ ì 체를 íìíê² ë©ëë¤.
ëí, ê°ì²´ì ìì±ì ë°ë³µí ë, íë¡í íì
ì²´ì¸ì ìë 모ë " ì´ê±° ê°ë¥í ìì±ì´ ì´ê±°ë©ëë¤. ê°ì²´ê° íë¡í íì
ì²´ì¸ì´ ìë itselfì ì ìë ìì±ì ê°ì§ê³ ìëì§ íì¸íë ¤ë©´, hasOwnProperty
ëë Object.hasOwn
ë©ìë를 ì¬ì©í´ì¼ í©ëë¤. [[Prototype]]
ì¼ë¡ null
ì´ ìë ê°ì²´ë¥¼ ì ì¸í 모ë ê°ì²´ë íë¡í íì
ì²´ì¸ìì ë ìëë¡ ì¬ì ìëì§ ìë í Object.prototype
ìì hasOwnProperty
를 ììí©ëë¤. 구체ì ì¸ ì를 ì ê³µí기 ìí´ ìì ê·¸ëí ìì ì½ë를 ì¬ì©íì¬ ì¤ëª
íê² ìµëë¤.
function Graph() {
this.vertices = [];
this.edges = [];
}
Graph.prototype.addVertex = function (v) {
this.vertices.push(v);
};
const g = new Graph();
// g ---> Graph.prototype ---> Object.prototype ---> null
g.hasOwnProperty("vertices"); // true
Object.hasOwn(g, "vertices"); // true
g.hasOwnProperty("nope"); // false
Object.hasOwn(g, "nope"); // false
g.hasOwnProperty("addVertex"); // false
Object.hasOwn(g, "addVertex"); // false
Object.getPrototypeOf(g).hasOwnProperty("addVertex"); // true
ì°¸ê³ : ìì±ì´ undefined
ì¸ì§ íì¸íë ê²ë§ì¼ë¡ë ì¶©ë¶íì§ ììµëë¤. ìì±ì´ ì¡´ì¬íë ë¨ìí ê°ì´ undefined
ì¸ ê²½ì°ë ììµëë¤.
JavaScriptë 모ë ëì ì´ê³ ë°íìì´ë©° ì ì íì
ì´ ì í ì기 ë문ì, Java ëë C++ìì ì¨ ê°ë°ììê²ë ë¤ì í¼ëì¤ë¬ì¸ ì ììµëë¤. 모ë ê²ì ê°ì²´(ì¸ì¤í´ì¤)ì´ê±°ë í¨ì(ìì±ì)ì´ë©° í¨ì ìì²´ë Function
ìì±ìì ì¸ì¤í´ì¤ì
ëë¤. ë¬¸ë² êµ¬ì±ì¸ "í´ëì¤"ë ë°íììë ìì±ì í¨ìì¼ ë¿ì
ëë¤.
JavaScriptì 모ë ìì±ì í¨ììë new
ì°ì°ìì í¨ê» ìëíë prototype
ì´ë¼ë í¹ì ìì±ì´ ììµëë¤. íë¡í íì
ê°ì²´ì ëí 참조ë ì ì¸ì¤í´ì¤ì ë´ë¶ [[Prototype]]
ìì±ì ë³µì¬ë©ëë¤. ì를 ë¤ì´, const a1 = new A()
를 ìííë©´, JavaScript(ë©ëª¨ë¦¬ì ê°ì²´ë¥¼ ìì±í í this
를 ì ìí A()
를 ì¤íí기 ì ì)ë a1.[[Prototype]] = A.prototype
ì ì¤ì í©ëë¤. ê·¸ë° ë¤ì ì¸ì¤í´ì¤ì ìì±ì ì ê·¼íë©´, JavaScriptë 먼ì í´ë¹ ê°ì²´ì ì§ì ì¡´ì¬íëì§ ì¬ë¶ë¥¼ íì¸íê³ , ê·¸ë ì§ ìì ê²½ì° [[Prototype]]
ìì ì°¾ìµëë¤. [[Prototype]]
ì ìíë ê°ì ì°¾ì ëê¹ì§ ì¬ê·ì ì¼ë¡ íìí©ëë¤. ì¦, a1.doSomething
, Object.getPrototypeOf(a1).doSomething
, Object.getPrototypeOf(Object.getPrototypeOf(a1)).doSomething
ììë¡ íìíë©°, ê°ì 찾거ë Object.getPrototypeOf
ë null
ì¼ ë íìì ì¢
ë£í©ëë¤. ì´ë prototype
ì ì ìë 모ë ìì±ì´ 모ë ì¸ì¤í´ì¤ìì í¨ê³¼ì ì¼ë¡ ê³µì ëë©°, ëì¤ì prototype
ì ì¼ë¶ë¥¼ ë³ê²½íê³ ë³ê²½ ì¬íì´ ëª¨ë 기존 ì¸ì¤í´ì¤ì ëíëëë¡ í ì ìë¤ë ê²ì ì미í©ëë¤.
ìì ììì const a1 = new A(); const a2 = new A();
ì¸ ê²½ì° a1.doSomething
ì ì¤ì ë¡ Object.getPrototypeOf(a1).doSomething
ì 참조íê³ , ì´ë ì ìí A.prototype.doSomething
ê³¼ ëì¼í©ëë¤. ì¦, Object.getPrototypeOf(a1).doSomething === Object.getPrototypeOf(a2).doSomething === A.prototype.doSomething
ì
ëë¤.
íë¡í íì ìì 모ë¸ì ì¬ì©íë ë³µì¡í ì½ë를 ìì±í기 ì ì íë¡í íì ìì 모ë¸ì ì´í´íë ê²ì´ íìì ì ëë¤. ëí, ì½ëìì íë¡í íì ì²´ì¸ì 길ì´ë¥¼ íì íì¬ íìí ê²½ì° ì±ë¥ 문ì 를 ë°©ì§í기 ìí´ ë¶í íì¸ì. ëí, ë´ì¥ íë¡í íì ì ìµì JavaScript 기ë¥ê³¼ì í¸íì±ì ìí ê²½ì°ê° ìëë©´ ì ë íì¥í´ìë ì ë©ëë¤.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4