μλ°μ€ν¬λ¦½νΈλ λͺ
λ Ήν(Imperative), ν¨μν(Functional), κ°μ²΄ μ§ν₯ νλ‘κ·Έλλ°(OOP)μ μ§μνλ νλ‘ν νμ
κΈ°λ°(Prototype-based) λ©ν° ν¨λ¬λ€μ μΈμ΄μ
λλ€. μ°λ¦¬λ μ΄ μ₯μμ μμνλ κ°λ
μΈ νλ‘ν νμ
μ λν΄ μμλ΄
λλ€.
νλ‘κ·Έλ¨μ μ¬λ¬ λ 립μ λ¨μμΈ κ°μ²΄(Object)μ μ§ν©μΌλ‘ νλ‘κ·Έλ¨μ νννλ €λ ν¨λ¬λ€μμ λλ€.
κ°μ²΄ μ§ν₯ νλ‘κ·Έλλ°μ νμ€μ μ‘΄μ¬νλ μ€μ²΄(μ¬λ¬Όκ³Ό κ°λ
μ λ»ν©λλ€)λ₯Ό νλ‘κ·Έλλ°μ μ λͺ©νλ μ² νμ μλμμ μμλ©λλ€. μλ₯Ό λ€μ΄ νμ€μμμ μ¬λ
μ νΉμ§κ³Ό μ±μ§μ λνλ΄λ μ΄λ¦
, μ±λ³
, λμ΄
λ± λ€μν μμ±(Attribute/Property) μ κ°μ§λλ€. μ΄λ₯Ό ꡬ체μ μΌλ‘ μ΄λ¦μ Amy, μ¬μμ΄κ³ 16μ΄μ΄μΌ.
νννλ©΄ κ·Έ λμμ νΉμ ν μ μμ£ .
μ, κ°μ²΄ μ§ν₯ νλ‘κ·Έλλ°μ μ΄λ₯Ό μ λͺ©μν΅λλ€. λ€μν μμ±μ λ§λ€μ΄λκ³ , νλ‘κ·Έλ¨μ νμν μμ±λ§ μΈλΆμ μΌλ‘ λ½μ νννλ©΄ μνλ λμμ νΉμ ν μ μκ² μ£ ? μ΄λ κ² νμν μμ±μΌλ‘ νννλ κ²μ μΆμν(Abstract)
λΌκ³ ν©λλ€. μ§κΈκ» μ°λ¦¬κ° μμ λ‘ νννλ κ°μ²΄λ₯Ό λ³ΌκΉμ?
- μ΄λ¦κ³Ό μ±λ³, λμ΄λΌλ μμ±μ κ°λ κ°μ²΄
const person = { name: 'amy', gender: 'female', age: 16 }
μ°λ¦¬λ μ΄λ‘μ¨ μ λ§μ κ°μ²΄ μ€μ personμ΄λΌλ κ°μ²΄λ₯Ό νΉμ νμ¬ μ νν μ μμ΅λλ€. μ¦, κ°μ²΄λ μμ±μΌλ‘ μ¬λ¬ κ°μ νλμ λ¨μλ‘ λ¬Άμ 볡ν©μ μΈ μλ£κ΅¬μ‘°
μ
λλ€. κ·Έλ λ€λ©΄ κ°μ²΄ μ§ν₯ νλ‘κ·Έλλ°μ 무μμΌκΉμ? μμ λ§ν κ°μ²΄μ μ§ν©μΌλ‘ νλ‘κ·Έλλ°μ νννλ λ°©λ²μ
λλ€. μμ λ₯Ό λ΄
μλ€.
- μ(Circle) κ°λ
μ κ°μ²΄λ‘ λνλ΄κΈ°
const circle = { // λ°μ§λ¦ radius: 5, // μμ μ§λ¦ getDiameter(){ return 2 * this.radius; }, // μμ λλ getPerimeter(){ return 2 * Math.PI * this.radius; }, // μμ λμ΄ getArea(){ return Math.PI * this.radius ** 2; } }; console.log(circle); // {radius: 5, getDiameter: Ζ, getPerimeter: Ζ, getArea: Ζ} console.log(circle.getDiameter()); // 10 console.log(circle.getPerimeter()); // 31.41592653589793 console.log(circle.getArea()); // 78.53981633974483
μμλ λ°μ§λ¦μ΄λΌλ μμ±μ΄ μλλ°, μ΄ μμ±μ μ(Circle)μ μν(State)λ₯Ό λνλ΄λ λ°μ΄ν°λΌ λ§νλ©° μ΄ μνλ₯Ό ν΅ν΄ μ΄λ€ κ²μ ꡬνλ κ±Έ λμμ΄λΌκ³ ν©λλ€. μ 리ν΄λ³ΌκΉμ?
κ°μ²΄ μ§ν₯ νλ‘κ·Έλλ°μ κ°μ²΄μ μνλ₯Ό λνλ΄λ λ°μ΄ν°μ μν λ°μ΄ν°λ₯Ό μ‘°μν μ μλ λμμ νλμ λ Όλ¦¬μ λ¨μλ‘ λ¬Άμ΅λλ€. μ¦, κ°μ²΄λ μν λ°μ΄ν°μ λμμ νλμ λ Όλ¦¬μ λ¨μλ‘ λ¬Άμ 볡ν©μ μλ£κ΅¬μ‘°μ΄λ©°, μ°λ¦¬κ° μκ³ μλ νλ‘νΌν°κ° μν λ°μ΄ν°, λ©μλκ° λμμ΄ λ©λλ€. μ΄λ° κ°μ²΄μ μΆκ°μ μΈ κΈ°λ₯μ μλμ κ°μμ.
- μμ λ§μ κΈ°λ₯μ μνν¨κ³Ό λμμ λ€λ₯Έ κ°μ²΄μ κ΄κ³(Relation)λ₯Ό κ°μ§λλ€.
- λ€λ₯Έ κ°μ²΄μ ν΅μ (λ©μΈμ§λ λ°μ΄ν°λ₯Ό μ‘μμ λ° μ²λ¦¬)ν μ μμ΅λλ€.
- λ€λ₯Έ κ°μ²΄μ μν λ°μ΄ν°μ λμμ
μμ
λ°μ μ μμ΅λλ€.
λ€μ μμν κ°λ μ΄ λμλ€μ. μμμ΄ λκΉμ?
νΉμ κ°μ²΄λ₯Ό λ€λ₯Έ κ°μ²΄κ° μμ(Inheritance)λ°μ κ·Έλλ‘ μ¬μ©ν μ μλ κ²μ λλ€.
μλ°μ€ν¬λ¦½νΈμ νλ‘ν νμ κΈ°λ°μ μμμ ꡬνν΄ κΈ°μ‘΄ μ½λλ₯Ό μ κ·Ήμ μΌλ‘ μ¬μ¬μ©ν©λλ€. μ΄λ μ½λμ μ€λ³΅μ μ κ±°νλλ° λ§€μ° ν¨μ¨μ μ΄μ£ . μ, μμ λ₯Ό 보기μ μμ μ°λ¦¬λ μμ κ°κ³Ό κ°μ²΄μ λν΄ λ°°μ μ΅λλ€. κ·Έ λΆλΆμ μ μκΈ°νλ©΄μ μ§νν΄λ³ΌκΉμ?
// μμ±μ ν¨μ(Constructor)
function Circle(radius) {
// νλ‘νΌν°
this.radius = radius;
// λ©μλ
this.getArea = function () {
return Math.PI * this.radius ** 2;
};
}
// λ°μ§λ¦ 1μ μΈμ€ν΄μ€(Instacne) μμ±
const circle1 = new Circle(1);
// λ°μ§λ¦ 2μ μΈμ€ν΄μ€(Instacne) μμ±
const circle2 = new Circle(2);
console.log(circle1.getArea === circle2.getArea); // false
console.log(circle1.getArea()); // 3.14...
console.log(circle2.getArea()); // 12.56...
μμ±μ ν¨μλ λμΌν νλ‘νΌν° ꡬ쑰λ₯Ό κ°λ κ°μ²΄λ₯Ό μ¬λ¬ κ° μμ±ν λ λ§€μ° μ μ©νμ£ . κ·Έλ¬λ ν° λ¬Έμ κ° μμ΅λλ€. this.radius
κ°μ νλ‘νΌν° κ°μ μΌλ°μ μΌλ‘ μΈμ€ν΄μ€λ§λ€ λ€λ¦
λλ€. κ°μ μνλ₯Ό κ°μ§λ€λ©΄ νλ‘νΌν°κ° κ°μ μλ μμ§λ§... κ·Έλ¬λ this.getArea()
κ°μ λ©μλλ λͺ¨λ μΈμ€ν΄μ€κ° λμΌν λ΄μ©μ λ©μλλ₯Ό μ¬μ©νμ£ .
μ€, κ·ΈλΌ μΈμ€ν΄μ€λ€μ λ©μλλ₯Ό 곡μ νλ ννκ° λ§λ κ² κ°μμ. κ·Έλ°λ° μμ μμ μμ console.log(circle1.getArea === circle2.getArea);
μ ꡬ문μ falseκ° μΆλ ₯λ©λλ€. μ΄κ²μ μΈμ€ν΄μ€λ₯Ό μμ±ν λλ§λ€ λͺ¨λ νλ‘νΌν°κ° μ¬ μμ±λλ©΄μ λͺ¨λ μΈμ€ν΄μ€κ° μ€λ³΅ μμ νλ€λ κ²μ μμ¬νμ£ .
μ΄ λ§μ μ½κ² νμλ©΄, λμΌν μμ±μ ν¨μλ‘ μμ±λ μΈμ€ν΄μ€κ° 100κ°λΌλ©΄ 100κ°μ getArea λ©μλκ° μ€λ³΅λλ€λ λ»μ λλ€. λΉμ°ν λ©λͺ¨λ¦¬λ₯Ό λλΉνκ² λκ³ , μ±λ₯(Performance)μ μ νμν€κ² λΌμ. μ°λ¦¬λ μ΄λ° ν° λ¬Έμ λ₯Ό νλ‘ν νμ κΈ°λ°μ μμμ ꡬνν¨μΌλ‘μ¨ ν΄κ²°ν μ μμ΅λλ€.
// μμ±μ ν¨μ(Constructor)
function Circle(radius) {
// νλ‘νΌν°
this.radius = radius;
}
// νλ‘ν νμ
Circle.prototype.getArea = function(){
return Math.PI * this.radius ** 2;
}
// λ°μ§λ¦ 1μ μΈμ€ν΄μ€(Instacne) μμ±
const circle1 = new Circle(1);
// λ°μ§λ¦ 2μ μΈμ€ν΄μ€(Instacne) μμ±
const circle2 = new Circle(2);
console.log(circle1.getArea === circle2.getArea); // true
console.log(circle1.getArea()); // 3.14...
console.log(circle2.getArea()); // 12.56...
console.log(circle1.getArea === circle2.getArea);
μ κ΅¬λ¬Έμ΄ trueκ° λμλ€μ! λ¬΄μ¨ μΌμΌκΉμ?
μ΄ λΉλ°μ λ°νμλ©΄ μλ°μ€ν¬λ¦½νΈ μμ§μ νλ‘ν νμ κΈ°λ°μ μμμ μν κ²μ λλ€. μ‘°κΈ λ μμΈν μ€λͺ νμλ©΄, Circle μμ±μ ν¨μκ° μμ±ν λͺ¨λ μΈμ€ν΄μ€λ μμ κ°μ²΄ μν μΈ Circle.prototypeμ λͺ¨λ νλ‘νΌν°μ λ©μλλ₯Ό μμ λ°κΈ° λλ¬Έμ΄μμ. getAreaλ Circleμ νλ‘ν νμ μΌλ‘ λ¨ νλλ§ μμ±λμ΄ ν λΉλμμ΅λλ€. κ·ΈλΌ Circleμ μμ±μ ν¨μλ‘ μμ±λ λͺ¨λ μΈμ€ν΄μ€λ getArea λ©μλλ₯Ό μμλ°μ μ¬μ©ν μ μκ² λΌμ.
μ¦, μμ μ μνλ₯Ό λνλ΄λ λ°μ΄ν°λ κ°λ³μ μΌλ‘ μμ νκ³ , λμΌν κΈ°λ₯μ λνλ΄λ λμμ μμμ ν΅ν΄ 곡μ νλ κ²μ΄μ£ . μ΄ κ²μ΄ μμμ΄ κ°μ§λ μ½λμ μ¬μ¬μ©μ± μ΄μ μ λλ€!
μλ°μ€ν¬λ¦½νΈμ λͺ¨λ κ°μ²΄λ μμ μ λΆλͺ¨ μν μ λ΄λΉνλ κ°μ²΄μ μ°κ²°λμ΄ μμ΅λλ€. μ΄λ κ°μ²΄ μ§ν₯ νλ‘κ·Έλλ°μ μμμ²λΌ λΆλͺ¨ κ°μ²΄μ κΈ°λ₯μ μμλ°μ μ¬μ©ν μ μκ² ν©λλ€. μ΄λ° λΆλͺ¨ κ°μ²΄λ₯Ό νλ‘ν νμ (Prototype) κ°μ²΄, μ€μ¬μ νλ‘ν νμ (Prototype)μ΄λΌκ³ ν΄μ.
λ΄λΆ μ¬λ‘―κ³Ό λ΄λΆ λ©μλμμ μΈκΈνλ― λͺ¨λ κ°μ²΄λ [[Prototype]]
μ΄λΌλ λ΄λΆ μ¬λ‘―μ κ°μ§κ³ , ν΄λΉ μ¬λ‘―μ μ μ₯λλ νλ‘ν νμ
μ κ°μ²΄ μμ± λ°©μμ μν΄ κ²°μ λ©λλ€.
β μ κΉ!
[[Prototype]]
μ μ§μ μ κ·Όμ λΆκ°λ₯ν΄λ,__proto__
μ κ·Όμ νλ‘νΌν°λ‘ λ΄λΆ μ¬λ‘―μ΄ κ°λ¦¬ν€λ νλ‘ν νμ μ κ°μ μ μΌλ‘ μ κ·Όν μ μμ£ ? κ·ΈλΌ μλμ νλ‘μΈμ€κ° κ°λ₯ν΄μ§λλ€.
- νλ‘ν νμ μ μμ μ constructor νλ‘νΌν°λ₯Ό ν΅ν΄ μμ±μ ν¨μμ μ κ·Όν μ μμ΅λλ€.
- μμ±μ ν¨μλ μμ μ prototype νλ‘νΌν°λ₯Ό ν΅ν΄ νλ‘ν νμ μ μ κ·Όν μ μμ΅λλ€.
κ²°κ΅ λͺ¨λ κ°μ²΄λ νλμ νλ‘ν νμ
μ κ°κ² λΌμ£ . λ°λΌμ λͺ¨λ νλ‘ν νμ
μ μμ±μ ν¨μμ μ°κ²°λμ΄ μλ€κ³ λ§ν μ μμ΅λλ€.
λ€μ μ₯μΌλ‘ λμ΄κ°κΈ° μ μ, μ κ·Όμ νλ‘νΌν°μΈ __proto__
μ λν΄ μΈκΈν©λλ€.
λͺ¨λ κ°μ²΄λ
__proto__
μ κ·Όμ νλ‘νΌν°λ‘ μμ μ νλ‘ν νμ μΈ[[ProtoType]]
λ΄λΆ μ¬λ‘―μ κ°μ μ μΌλ‘ μ κ·Όν μ μμ΅λλ€.
νμ¬ λΈλΌμ°μ μ¬μμ΄ μ λ°μ΄νΈκ° λμλμ§, [[Prototype]]μ΄ μΆλ ₯λλ κ²μ λ³Ό μ μμ΅λλ€. μ΄ λ΄μ©μ 체ν¬ν΄λκ³ λ€μ νμΈν΄μΌκ² μ΄μ. π
μ κ·Έλ¦Όμ νλμ λ°μ€λ objects
λΌλ κ°μ²΄μ νλ‘ν νμ
μΈ Object.prototype
μ
λλ€. μΆλ ₯μλ [[Prototype]]
μΌλ‘ λμ΄ μμ§λ§, λ΄λΆμ μΈ λμμ __prototype__
μ κ·Όμ νλ‘νΌν°λ₯Ό ν΅ν΄ [[Prototype]]
λ΄λΆ μ¬λ‘―μ΄ κ°λ¦¬ν€λ Object.prototype κ°μ²΄μ μ κ·Όν κ²°κ³Όλ₯Ό νμν΄μ€ κ²μ΄μ£ .
__proto__
μ λν΄ μ 리νκ³ λμ΄κ°μ£ .
-
__proto__
λ μ κ·Όμ νλ‘νΌν°μ λλ€.const data = Object.getOwnPropertyDescriptor(Object.prototype, '__proto__'); console.log(data);
- Object.prototypeμ μ κ·Όμ νλ‘νΌν°
__proto__
λ μ κ·Όμ ν¨μλ₯Ό ν΅ν΄[[Prototype]]
λ΄λΆμ μ¬λ‘― κ°μΈ νλ‘ν νμ μ μ·¨λ(Get) νκ±°λ ν λΉ(Set) ν©λλ€. __proto__
μ κ·Όμ νλ‘νΌν°λ₯Ό μ¬μ©νλ νλ‘μΈμ€λ μ΄λ μ΅λλ€.const obj = {}; const parent = {x : 1}; // 1λ² obj.__proto__; // 2λ² obj.__proto__ = parent; console.log(obj.x); // 1
- νλ‘ν νμ
μ κ·Ό μ :
__proto__
μ getter ν¨μ[[Get]]
νΈμΆ - νλ‘ν νμ
ν λΉ μ :
__proto__
μ setter ν¨μ[[Set]]
νΈμΆ
- νλ‘ν νμ
μ κ·Ό μ :
- Object.prototypeμ μ κ·Όμ νλ‘νΌν°
-
__proto__
μ κ·Όμ νλ‘νΌν°λ μμμ ν΅ν΄ μ¬μ©λ©λλ€.-
ν΄λΉ νλ‘νΌν°λ κ°μ²΄κ° μ§μ μμ νλ κ²μ΄ μλ Object.prototypeμ νλ‘νΌν°μ΄λ―λ‘ λͺ¨λ κ°μ²΄λ μμμ ν΅ν΄
Object.prototype.__proto__
λ₯Ό μ¬μ©ν μ μμ΅λλ€.Object.prototypeμ λν΄μλ μλμ νλ‘ν νμ 체μΈμμ λ€λ£¨λ κ±±μ λ§μκ³ νλ‘ν νμ 체μΈμ μ΅μμ κ°μ²΄λ‘μ Object.prototypeμ ν λΉλ νλ‘νΌν°μ λ©μλλ λͺ¨λ κ°μ²΄μ μμλλ€λ κ²λ§ μμλμΈμ.
const circle = { radius: 5}; // 1λ² console.log(circle.hasOwnProperty('__proto__')); // κ²°κ³Ό : false // 2λ² console.log(Object.getOwnPropertyDescriptor(Object.prototype, '__proto__')); // κ²°κ³Ό : {enumerable: false, configurable: true, get: Ζ, set: Ζ} // 3λ² console.log({}.__proto__ === Object.prototype); // κ²°κ³Ό : true
- 1λ² : circle κ°μ²΄λ
__proto__
λ₯Ό μμ νμ§ μμ΅λλ€. - 2λ² :
__proto__
νλ‘νΌν°λ λͺ¨λ κ°μ²΄μ νλ‘ν¬νμ κ°μ²΄μΈ Object.prototypeμ μ κ·Όμ νλ‘νΌν°μ λλ€. - 3λ² : λͺ¨λ κ°μ²΄λ Object.prototypeμ μ κ·Όμ νλ‘νΌν°
__proto__
λ₯Ό μμλ°μ μ μμ΅λλ€.
-
__proto__
μ κ·Όμ νλ‘νΌν°λ₯Ό ν΅ν΄ νλ‘ν νμ μ μ κ·Όνλ μ΄μ- μνΈ μ°Έμ‘°λ‘ νλ‘ν νμ
체μΈμ΄ μμ±λλ κ²μ λ°©μ§νκΈ° μν΄μμ
λλ€.
μνΈ μ°Έμ‘°(Cross-reference), μν μ°Έμ‘°(Circular-reference)λΌκ³ λ νλ©°, μλ‘κ° μλ‘λ₯Ό μ°Έμ‘°νλ κ΄κ³λ₯Ό λ§ν©λλ€.
const person1 = {}; const person2 = {}; person1.__proto__ = person2; person2.__proto__ = person1; // TypeError: Cyclic __proto__ value
-
μλ¬κ° λ°μνμ§ μλλ€λ©΄ μ΄λ¨κΉμ? μκ°ν΄λ΄ μλ€. νλ‘ν νμ μλ 체μΈμ΄ μ‘΄μ¬νλλ°, μ΄ μ²΄μΈμ μ’ μ (λ)μ΄ μλ‘λ₯Ό μ°Έμ‘°νκ² λλ©΄ 무νμ μΌλ‘ λ°λ³΅λκ² μ£ ? μ΄λ κ² λ§μ΄μμ.
-
λ°λΌμ 무쑰건 νλ‘ν νμ μ κ΅μ²΄ν μ μκ² μλ°©ν₯μ΄ μλ, λ¨λ°©ν₯μΌλ‘ μ°κ²°λκ²λ
__proto__
μ κ·Όμ νλ‘νΌν°λ₯Ό ν΅ν΄ μ κ·Ό λ° κ΅μ²΄κ° κ°λ₯νλλ‘ μ μ½μ κ±Έμ΄λμ κ²μ λλ€.
-
- μνΈ μ°Έμ‘°λ‘ νλ‘ν νμ
체μΈμ΄ μμ±λλ κ²μ λ°©μ§νκΈ° μν΄μμ
λλ€.
__proto__
μ κ·Όμ νλ‘νΌν°λ₯Ό μ§μ μ¬μ©νμ§ λ§μΈμ.- λ³Έλ proto μ κ·Όμ νλ‘νΌν°λ ES5κΉμ§ λΉνμ€μ΄μμ΅λλ€. κ·Έλ¬λ λͺλͺ λΈλΌμ°μ κ° μ΄λ₯Ό μ§μνκ³ μμμΌλ―λ‘ νΈνμ±μ κ³ λ €νμ¬ ES6λ₯Ό __proto__λ₯Ό νμ€μΌλ‘ μ±νν κ² λΏμ λλ€.
- κΆμ₯λμ§ μλ μ΄μ λ λͺ¨λ κ°μ²΄κ°
__proto__
μ κ·Όμ νλ‘νΌν°λ₯Ό μ¬μ©ν μ μλ κ²μ΄ μλκΈ° λλ¬Έμ΄μ£ . μλμ κ²½μ°__proto__
λ₯Ό μμλ°μ§ λͺ»ν©λλ€.const obj = Object.create(null);
- μλ‘ κ°μ²΄λ₯Ό μμ±νλ―λ‘, νλ‘ν νμ
μ’
μ μ μ‘΄μ¬νλ κ°μ²΄κ° λλ―λ‘
__proto__
κ° nullμ΄ λ©λλ€.
- μλ‘ κ°μ²΄λ₯Ό μμ±νλ―λ‘, νλ‘ν νμ
μ’
μ μ μ‘΄μ¬νλ κ°μ²΄κ° λλ―λ‘
- λ°λΌμ μλμ κ°μ΄ μ¬μ©ν΄μ£ΌμΈμ. κΈ°λ₯μ μ ννκ² μΌμΉν©λλ€.
- νλ‘ν νμ
μ°Έμ‘° μ·¨λ μ :
Object.getPrototypeOf()
, ES5μμ λμ - νλ‘ν νμ
κ΅μ²΄ μ :
Object.setPrototypeOf()
, ES6μμ λμ
- νλ‘ν νμ
μ°Έμ‘° μ·¨λ μ :
ν¨μ κ°μ²΄λ§μ΄ μμ νλ νλ‘ν νμ νλ‘νΌν°κ° μ‘΄μ¬ν©λλ€. μ΄λ μμ±μ ν¨μκ° μμ±ν μΈμ€ν΄μ€μ νλ‘ν νμ μ κ°λ¦¬ν΅λλ€.
μ΄κ²μ΄ μΌλ° κ°μ²΄μ ν¨μ κ°μ²΄κ° λ€λ₯Έ νλ‘ν νμ
μ κ°λ μ΄μ μ
λλ€. κ·Έλ¬λ μμ±μ ν¨μλ‘ νΈμΆν μ μλ non-constructor ν¨μ
λ νλ‘ν νμ
νλ‘νΌν°κ° μ‘΄μ¬νμ§λ, μμ±νμ§λ μμ΅λλ€.
- μ’
λ₯λ³λ‘ μμ λ₯Ό λ³ΌκΉμ?
// 1λ² : ν¨μ κ°μ²΄(constructor) - ν¨μ μ μΈλ¬Έ console.log((function(){}).hasOwnProperty('prototype')); // κ²°κ³Ό : true // 2λ² : ν¨μ κ°μ²΄(constructor) - ν¨μ ννμ const func = function(){}; console.log(func.hasOwnProperty('prototype')); // κ²°κ³Ό : true // 3λ² : μΌλ° κ°μ²΄ console.log(({}).hasOwnProperty('prototype')); // κ²°κ³Ό : false // 4λ² : νμ΄ν ν¨μ(non-constructor) console.log((() => {}).hasOwnProperty('prototype'), (() => {}).prototype); // κ²°κ³Ό : false, undefined // 5λ² : λ©μλ μΆμ½ νν(non-constructor) const obj = {foo(){}}; console.log(obj.foo.hasOwnProperty('prototype'), obj.foo.prototype); // κ²°κ³Ό : false, undefined
- μ¦, λͺ¨λ κ°μ²΄κ° κ°μ§ proto μ κ·Όμ νλ‘νΌν°μ ν¨μ κ°μ²΄κ° κ°μ§ prototype νλ‘νΌν°λ λμΌν νλ‘ν νμ μ κ°λ¦¬ν΅λλ€. μ¬μ© λͺ©μ μ λ€λ₯΄μ§λ§μ.
-
νλ‘ν νμ μ μ¬μ© λͺ©μ ?
κ΅¬λΆ μμ κ° μ¬μ© 주체 μ¬μ© λͺ©μ __proto__
μ κ·Όμ νλ‘νΌν°λͺ¨λ κ°μ²΄ νλ‘ν νμ μ°Έμ‘° λͺ¨λ κ°μ²΄ κ°μ²΄μ μκΈ°μμ νλ‘ν νμ
μ κ·Όprototype
νλ‘νΌν°constructor νλ‘ν νμ μ°Έμ‘° μμ±μ ν¨μ μμ±μ ν¨μκ° μμ μ΄ μμ±ν
μΈμ€ν΄μ€μ νλ‘ν νμ ν λΉ// μμ±μ ν¨μ function Human(name){ this.name = name; } console.log(Human.prototype); // {constructor: Ζ} console.log(Human.__proto__); // Ζ () { [native code] } // μΌλ° κ°μ²΄ const human = {name: 'amy'}; console.log(human.prototype); // undefined console.log(human.__proto__); // {constructor: Ζ, __defineGetter__: Ζ,Β β¦}
μ¬μ© λͺ©μ ...μ μ‘°κΈ μ΄ν΄νκΈ° νλλ€μ. μ°μ λμμ΄ μ΄λ»κ² λλμ§ νμΈν΄λ΄ μλ€(μ¬μ© λͺ©μ μ μΆκ°λ‘ μμλ΄ λλ€).
- μμ±μ ν¨μλ‘ κ°μ²΄λ₯Ό μμ±νκ³ νλ‘ν νμ
κ°μ²΄μ μ κ·Όνκ³ λΉκ΅νκΈ°
function Human(name){ this.name = name; } let person = {name: 'amy'}; console.log(Human.prototype, "||||", person.prototype); // κ²°κ³Ό : {constructor: Ζ} '||||' undefined console.log(Human.__proto__, "||||", person.__proto__); // κ²°κ³Ό : Ζ () { [native code] } '||||' {constructor: Ζ, __defineGetter__: Ζ,Β β¦} person = new Human('amy'); console.log(Human.prototype, "||||", person.prototype); // κ²°κ³Ό : {constructor: Ζ} '||||' undefined console.log(Human.__proto__, "||||", person.__proto__); // κ²°κ³Ό : Ζ () { [native code] } '||||' {constructor: Ζ} console.log(Human.prototype === person.__proto__); // κ²°κ³Ό : true
-
μ¬ν λΉν
person
μ __proto__μ μμ±μ ν¨μμ prototypeμ΄ λμΌν νλ‘ν νμ μ κ°λ¦¬ν€λ κ±Έ νμΈν μ μμ΅λλ€. κ·Έλ¦ΌμΌλ‘ 보면 μ΄λ κ² λκ² μ£ ? -
-
μ, λ€λ₯΄κ² λμνλ κ²λ μμλλ°, νλ‘ν νμ
μ λν μꡬμ¬μ κΉμ΄μ Έλ§ κ°λλ€. μ΄λ²μλ μμ μ½μ μΆλ ₯μμ νμΈνλ― νμ μΆλ ₯λμλ constructor νλ‘νΌν°
λ₯Ό νμΈν΄λ³Ό λμ
λλ€.
λͺ¨λ νλ‘ν νμ μ constructor νλ‘νΌν°λ₯Ό κ°μ΅λλ€.
constructor νλ‘νΌν°λ prototype νλ‘νΌν°λ‘ μμ μ μ°Έμ‘°νκ³ μλ μμ±μ ν¨μλ₯Ό κ°λ¦¬ν€λ©°, μ΄λ° μ°κ²°μ μμ±μ ν¨μκ° μμ±λ λμ μ΄λ€μ§λλ€.
-
νλ‘μΈμ€λ‘ μ΄ν΄ν΄λ³ΌκΉμ?
// μμ±μ ν¨μ function Human(name){ this.name = name; } // μΈμ€ν΄μ€ μμ± const person = new Human('amy'); console.log(person.constructor === Human); // true
- Human μμ±μ ν¨μλ‘ person μ΄λΌλ μΈμ€ν΄μ€(κ°μ²΄)λ₯Ό μμ±ν©λλ€.
- person κ°μ²΄λ constructorκ° μμ§λ§ Human.prototypeμλ constructor νλ‘νΌν°κ° μμ£ .
- λ°λΌμ person κ°μ²΄λ Human.prototypeμ constructor νλ‘νΌν°λ₯Ό μμ λ°μ μ¬μ©ν©λλ€.
- μ΄λ₯Ό κ·Έλ €λ³΄λ©΄ μ΄ν΄κ° λΉ λ₯΄κ² μ£ ?
리ν°λ΄μ μν κ°μ²΄ μμ± λ°©μμ²λΌ λͺ μμ μΌλ‘ new μ°μ°μμ ν¨κ» μμ±μ ν¨μλ₯Ό νΈμΆν΄ μΈμ€ν΄μ€λ₯Ό μμ±νμ§ μλ κ°μ²΄ μμ± λ°©μλ μ‘΄μ¬ν©λλ€.
리ν°λ΄λ‘ μμ±λ κ°μ²΄λ νλ‘ν νμ μ μ‘΄μ¬ν©λλ€. λ¨, νλ‘ν νμ μ constructorκ° λ°λμ κ°μ²΄λ₯Ό μμ±ν μμ±μ ν¨μλ₯Ό κ°λ¦¬ν¨λ€κ³ λ¨μ ν μ μμ΅λλ€.
- μλ μμ λ₯Ό λ΄
μλ€.
const num = 3; console.log(num.constructor === Number); const str = 'str'; console.log(str.constructor === String); const bool = true; console.log(bool.constructor === Boolean); const obj = {}; console.log(obj.constructor === Object); const add = function(a, b){ return a + b }; console.log(add.constructor === Function); const arr = [1, 2, 3]; console.log(arr.constructor === Array); const regexp = /is/gi; console.log(regexp.constructor === RegExp);
- κ° νμ
μ 리ν°λ΄λ‘ μ μΈνμμλ μμ±μ ν¨μμ constructor νλ‘νΌν°λ‘ μ°κ²°λμ΄ μμ΅λλ€. κ·Έλ λ€λ©΄ μ΄λ κ² μκ°ν μ μκ² μ£ ?
리ν°λ΄μ μν΄ μμ±λ κ°μ²΄λ μμ±μ ν¨μλ‘ μμ±λμμ?
- μΈλΆμ μΌλ‘λ λ€λ₯΄μ§λ§, ν° νμμ 보면 κ°μ΅λλ€. λ§μμ, μ΄λ €μ΄ λ§μ
λλ€. 리ν°λ΄ νκΈ°λ²μ μν΄ μμ±λ κ°μ²΄λ μμμ μν νλ‘ν νμ
μ΄ νμν©λλ€. κ²°κ΅
κ°μμ μΈ μμ±μ ν¨μ
λ₯Ό κ°κ² λλ κ±°μ£ .
- κ° νμ
μ 리ν°λ΄λ‘ μ μΈνμμλ μμ±μ ν¨μμ constructor νλ‘νΌν°λ‘ μ°κ²°λμ΄ μμ΅λλ€. κ·Έλ λ€λ©΄ μ΄λ κ² μκ°ν μ μκ² μ£ ?
μμΈν λ΄ μλ€. νλ‘ν νμ μ μμ±μ ν¨μκ° μμ±λ λ κ°μ΄ μμ±λκ³ , prototypeκ³Ό constructor νλ‘νΌν°μ μν΄ μ°κ²°λμ£ ? κ·Έλ λ€λ κ²μ νλ‘ν νμ κ³Ό μμ±μ ν¨μλ νμ μ(pari)μΌλ‘ μ‘΄μ¬νλ€λ λ»μ λλ€.
μ κΉ κΈμ΄ κΈΈμ΄μ§λ―λ‘ λ΄λΆ λμκ³Ό μΆμ μ°μ°μ λν΄ κΆκΈνμ§ μλ€λ©΄ λμ΄κ°μΈμ.
μΆμ μ°μ°(Abstract Operation), ECMAScript μ¬μμμ λ΄λΆ λμ ꡬν μκ³ λ¦¬μ¦μ ννν κ²μΌλ‘ ν¨μμ μ μ¬ν μμ¬ μ½λ(Pseudo Code)μ λλ€.
- κ³ μ ν κ°μ²΄
%Object%
μ λλ€. - μ μ κ°μ²΄μ μ μΈλ κ°μ²΄ νλ‘νΌν°μ μ΄κΈ° κ°μ λλ€.
- μμ±μλ‘ νΈμΆλ λ μλ‘μ΄ μΌλ° κ°μ²΄λ₯Ό μμ±ν©λλ€.
- μμ±μκ° μλ ν¨μλ‘ νΈμΆλ λ νμ λ³νμ μνν©λλ€.
- νμ λΆλ₯κ° κ°λ₯νλλ‘ μ€κ³λμμ΅λλ€. ν΄λμ€ μ μμ μμ κ°μΌλ‘ μ¬μ©ν μ μμ΅λλ€.
- NewTargetμ΄ μ μλμ§ μμκ±°λ νμ± ν¨μμΈ κ²½μ°
- λ°ν : OrdinaryCreateFromConstructor(NewTarget,
"%Object.prototype%"
).
- λ°ν : OrdinaryCreateFromConstructor(NewTarget,
- κ°μ΄ μ μλμ§ μμκ±°λ nullμΈ κ²½μ°
- λ°ν : OrdinaryObjectCreate(
"%Object.prototype%"
).
- λ°ν : OrdinaryObjectCreate(
- κ·Έ μΈλ κ°μ κ°μ²΄λ‘ λ§λ€μ΄ λ°νν©λλ€.
- κ°μ²΄ μμ±μ ν¨μμ "κΈΈμ΄" μμ±μ 1μ λλ€.
- λ°ν : OrdinaryObjectCreate(
"%Object.prototype%"
)
- OrdinaryObjectCreate(
"%Object.prototype%"
)μ μν΄ λΉ κ°μ²΄λ₯Ό μμ± - νλ‘νΌν° μ μ 리μ€νΈμ νλ‘νΌν° μ μ μ°μ°μ κ±°μΉ ν trueμΈ μΈμ κ°μ²΄λ₯Ό λ°νν©λλ€.
- κ°μ²΄λ₯Ό λ°νν©λλ€.
μ, κΈ΄ κΈμ΄ λλ¬μ΅λλ€. μ 리νμλ©΄, 리ν°λ΄μ μν΄ μμ±λ κ°μ²΄λ μμ±μ ν¨μμ μν΄ μμ±λ κ°μ²΄κ° μλλ―λ‘ μμ± κ³Όμ
, μ€μ½ν
, ν΄λ‘μ
λ±μ λ―Έλ¬ν μ°¨μ΄κ° μμ§λ§ μμ±λ κ°μ²΄λ‘μ λμΌν νΉμ±μ κ°κ² λλ―λ‘ λ³Έμ§μ μΈ μ°¨μ΄λ μλ€λ κ²μ΄ μ΄ νμ΄μ§μ κ²°λ‘ μ
λλ€.
λͺ¨λ κ°μ²΄λ μμ±μ ν¨μμ μ°κ²°λμ΄ μμ΅λλ€.
λ€μ ν λ² μΈκΈνμλ©΄, νλ‘ν νμ μ μμ±μ ν¨μκ° μμ±λλ μμ μ κ°μ΄ μμ±λ©λλ€.
μμ±μ ν¨μλ‘μ νΈμΆν μ μλ constructorλ ν¨μ μ μκ° νκ°λμ΄ ν¨μ κ°μ²΄λ₯Ό μμ±νλ μμ μ νλ‘ν νμ λ λλΆμ΄ μμ±λ©λλ€.
- μ½λλ‘ μ΄ν΄ λ³ΌκΉμ?
// 1λ² : constructor ν¨μ function Person(name) { this.name = name; } console.log(Person.prototype); // {constructor: f} // 2λ² : non-constructor ν¨μ const Human = (name) => { this.name = name; } console.log(Human.prototype); // undefined
- 1λ²μΈ ν¨μ μ μΈλ¬Έμ λ°νμ μ΄μ μ μλ°μ€ν¬λ¦½νΈ μμ§μ μν΄ λ¨Όμ μ€ν(νκ°)λλ―λ‘ κ°μ₯ μ°μ μ μΌλ‘ ν¨μ κ°μ²΄κ° λλ©°, νλ‘ν νμ λ κ°μ΄ μμ±λ©λλ€. κ·Έλ¬λ 2λ²μΈ νμ΄ν ν¨μλ μμ±μκ° μμ΅λλ€. λ°λΌμ νλ‘ν νμ λ μμ±λμ§ μμμ.
μμ μμ μ²λΌ μμ±λ κ°μ²΄λ νλ‘ν νμ μ κ°μ§κ³ , Person.prototypeμ νλ‘ν νμ λ μ‘΄μ¬νλ―λ‘ μ΅μμ νλ‘ν νμ μ Object.prototypeμ΄ λ©λλ€. κ·Έ λ§μ μμ±λ νλ‘ν νμ μ νλ‘ν νμ μ μΈμ λ Object.prototypeμ΄λΌλ κ²μ λλ€.
λͺ¨λ λΉνΈμΈ μμ±μ ν¨μλ μ μ κ°μ²΄κ° μμ±λλ μμ μ μμ±λλ©°, μμ±λ νλ‘ν νμ μ λΉνΈμΈ μμ±μ ν¨μμ prototype νλ‘νΌν°μ λ°μΈλ©λ©λλ€.
μΌλ° ν¨μμ λ§μ°¬κ°μ§λ‘ λΉνΈμΈ μμ±μ ν¨μκ° μμ±λλ μμ μ νλ‘ν νμ
μ΄ μμ±λ©λλ€
.
μ μ κ°μ²΄(Gloabl Object)λ λ°νμ μ΄μ μ μλ°μ€ν¬λ¦½νΈ μμ§μ μν΄ μμ±λλ νΉμν κ°μ²΄μ λλ€. λμ€μ λ μμΈν μμλ΄ λλ€.
보μλ λ°μ κ°μ΄ μμ±μ ν¨μμ νλ‘ν νμ
μ μ΄λ―Έ κ°μ²΄λ‘ μ‘΄μ¬νλ©° κ°μ²΄λ₯Ό μμ±νλ©΄ νλ‘ν νμ
μ μμ±λ κ°μ²΄μ [[Prototype]]
λ΄λΆ μ¬λ‘―μ ν λΉλ©λλ€. μ΄λ‘μ¨ μμ±λ κ°μ²΄κ° νλ‘ν νμ
μ μμλ°κ² λλ κ±°μ£ .
2021-09-24, μ 리 μ€ μλ³λ λ΄μ©μΌλ‘ μ λ€λ₯Έμ§ μ΄ν΄ν΄μΌ ν κ²
- λ΄λΆ μ¬λ‘―μ μ κ·Όμ΄ λΆκ°λ₯ν΄μ __proto__λ₯Ό ν΅ν΄ μ κ·Όνλ€κ³ νλλ°, μ€μ ν¬λ‘λμ λΈλΌμ°μ μ κ°λ°μ λꡬμμ κ°μ²΄λ ν¨μλ₯Ό μ μΈνκ³ μ‘°ννλ©΄
[[Prototype]]
μ΄ μΆλ ₯λλ€μ. μΈμ λ°λ κ±ΈκΉμ?
TODO
- μ°Έμ‘° Link
- __proto__λ₯Ό μ§μ μ¬μ©νμ§ λ§λΌκ³ νλλ°, μ΄μ λ λκΉμ?
[[Prototype]]
κ°μ²΄μ λ³κ²½μ μ΅μ μλ°μ€ν¬λ¦½νΈ μμ§μ΄ νλ‘νΌν° μ κ·Όμ μ΅μ ννλ λ°©λ²
μ λ°λΌ λͺ¨λ λΈλΌμ°μ μ μμ§μμ λ§€μ° λλ¦¬κ² λμν©λλ€.
λν [[Prototype]]
μ μ§μ λ³κ²½νμ¬ κ°μ²΄μ μμμ΄ μμ λλ obj.__proto__ = ...
λ¬Έμ λͺ¨λ μ½λκ° μ κ·Όμ΄ κ°λ₯νλλ‘ μλμΉ μκ² νμ₯λ μ μμΌλ©°, μ΄λ κ΄λ²μνκ² μ±λ₯μ μ νλ₯Ό μΌμΌν΅λλ€. μ΄λ° λΆκ° ν¨κ³Ό(Side Effect)λ λ¨μν λ¬Έ(statements)μ΄ μ€νλλ λμλ§ κ·ΈμΉμ§ μκ³ μ§μμ μΌλ‘ μν₯μ λ―ΈμΉκ² λμ£ . λ°λΌμ μ±λ₯μ ν₯μμν€κ³ μΆλ€λ©΄ κ°μ²΄μ μ§μ μ μΈ [[Prototype]]
λ³κ²½μ νΌν΄μΌ ν©λλ€.
λ¬Όλ‘ κ·Έ ν΄κ²°μ±
μΌλ‘ λ§μ λ°©λ²μ΄ μμΌλ©°, κ·Έ μ€ νλμΈ Object.create()
λ₯Ό μ¬μ©ν΄ μνλ νλ‘ν νμ
κ°μ²΄λ₯Ό μλ‘ μμ±ν μ μμ΅λλ€.
- λκ° λ€λ₯Έ κ±΄μ§ μ΄ν΄λ νλλ°... μ λ€λ₯Έ κ±ΈκΉμ? μ€λͺ μ΄ νμν΄μ.
TODO
- μ°Έμ‘° Link
-
constructor νλ‘νΌν°λ prototype νλ‘νΌν°λ‘ μμ μ μ°Έμ‘°νκ³ μλ μμ±μ ν¨μλ₯Ό κ°λ¦¬ν€λ©°, μ΄λ° μ°κ²°μ μμ±μ ν¨μκ° μμ±λ λμ μ΄λ€μ§λλ€
λΌκ³ μ΄ν΄νλλ°, κ·ΈλΌ μλμ κ²½μ°λ μ΄λ»κ² μ€λͺ ν΄μΌ ν κΉμ? -
ν΄λΉ μμ λ‘ μ΄ν΄ν κ²μ
__proto__
λ Object.prototypeλ§μ΄ μμ νκ³ , λ€λ₯Έ κ°μ²΄λ€μλΉλ € μ΄λ€
μμ΅λλ€.const circle = { radius: 5}; // 1λ² console.log(circle.hasOwnProperty('__proto__')); // κ²°κ³Ό : false // 2λ² console.log(Object.getOwnPropertyDescriptor(Object.prototype, '__proto__')); // κ²°κ³Ό : {enumerable: false, configurable: true, get: Ζ, set: Ζ} // 3λ² console.log({}.__proto__ === Object.prototype); // κ²°κ³Ό : true
- μ΄ν΄νλλ‘ μλνκ³ , μ νν κ² κ°μ΅λλ€.
-
κ·Έλ°λ°...?
// 3λ² : μΌλ° κ°μ²΄ console.log(({}).hasOwnProperty('prototype')); // κ²°κ³Ό : false
- μ΄κ±΄ μ falseμΌκΉμ?
TODO
{}
λ μμ±μ ν¨μ(new Object())μ μν΄ μμ±λλ―λ‘ μμ±μ ν¨μμ μΈμ€ν΄μ€μΈ 건 μκ² μ΅λλ€.
2021-09-29, InSeong-Soκ° μ€ν°λμκ³Ό μ¨λΌμΈ μ€ν°λ μ§ννλ©΄μ μλ¬Έμ μ κ°κ³ ν΄κ²°ν λ΄μ©
- μ 리ν΄μΌν¨
- μ 리ν΄μΌν¨
- μ 리ν΄μΌν¨