Skip to content

Latest commit

Β 

History

History
688 lines (470 loc) Β· 28.6 KB

prototype.md

File metadata and controls

688 lines (470 loc) Β· 28.6 KB

μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” λͺ…λ Ήν˜•(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)λ₯Ό λ‚˜νƒ€λ‚΄λŠ” 데이터라 λ§ν•˜λ©° 이 μƒνƒœλ₯Ό 톡해 μ–΄λ–€ 것을 κ΅¬ν•˜λŠ” κ±Έ λ™μž‘μ΄λΌκ³  ν•©λ‹ˆλ‹€. μ •λ¦¬ν•΄λ³ΌκΉŒμš”?

객체 지ν–₯ ν”„λ‘œκ·Έλž˜λ°μ€ 객체의 μƒνƒœλ₯Ό λ‚˜νƒ€λ‚΄λŠ” 데이터와 μƒνƒœ 데이터λ₯Ό μ‘°μž‘ν•  수 μžˆλŠ” λ™μž‘μ„ ν•˜λ‚˜μ˜ 논리적 λ‹¨μœ„λ‘œ λ¬ΆμŠ΅λ‹ˆλ‹€. 즉, κ°μ²΄λŠ” μƒνƒœ 데이터와 λ™μž‘μ„ ν•˜λ‚˜μ˜ 논리적 λ‹¨μœ„λ‘œ 묢은 볡합적 자료ꡬ쑰이며, μš°λ¦¬κ°€ μ•Œκ³  μžˆλŠ” ν”„λ‘œνΌν‹°κ°€ μƒνƒœ 데이터, λ©”μ„œλ“œκ°€ λ™μž‘μ΄ λ©λ‹ˆλ‹€. 이런 객체의 좔가적인 κΈ°λŠ₯은 μ•„λž˜μ™€ κ°™μ•„μš”.

  1. μžμ‹ λ§Œμ˜ κΈ°λŠ₯을 μˆ˜ν–‰ν•¨κ³Ό λ™μ‹œμ— λ‹€λ₯Έ 객체와 관계(Relation)λ₯Ό κ°€μ§‘λ‹ˆλ‹€.
  2. λ‹€λ₯Έ 객체와 톡신(λ©”μ„Έμ§€λ‚˜ 데이터λ₯Ό μ†‘μˆ˜μ‹  및 처리)ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  3. λ‹€λ₯Έ 객체의 μƒνƒœ 데이터와 λ™μž‘μ„ 상속받을 수 μžˆμŠ΅λ‹ˆλ‹€.

λ‹€μ‹œ μƒμ†Œν•œ κ°œλ…μ΄ λ‚˜μ™”λ„€μš”. 상속이 λ­˜κΉŒμš”?


상속과 ν”„λ‘œν† νƒ€μž…

νŠΉμ • 객체λ₯Ό λ‹€λ₯Έ 객체가 상속(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__ μ ‘κ·Όμž ν”„λ‘œνΌν‹°

λͺ¨λ“  κ°μ²΄λŠ” __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
      1. ν”„λ‘œν† νƒ€μž… μ ‘κ·Ό μ‹œ : __proto__의 getter ν•¨μˆ˜ [[Get]] 호좜
      2. ν”„λ‘œν† νƒ€μž… ν• λ‹Ή μ‹œ : __proto__의 setter ν•¨μˆ˜ [[Set]] 호좜

  • __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이 λ©λ‹ˆλ‹€.
    • λ”°λΌμ„œ μ•„λž˜μ™€ 같이 μ‚¬μš©ν•΄μ£Όμ„Έμš”. κΈ°λŠ₯은 μ •ν™•ν•˜κ²Œ μΌμΉ˜ν•©λ‹ˆλ‹€.
      1. ν”„λ‘œν† νƒ€μž… μ°Έμ‘° 취득 μ‹œ : Object.getPrototypeOf(), ES5μ—μ„œ λ„μž…
      2. ν”„λ‘œν† νƒ€μž… ꡐ체 μ‹œ : Object.setPrototypeOf(), ES6μ—μ„œ λ„μž…

ν•¨μˆ˜ 객체의 prototype ν”„λ‘œνΌν‹°

ν•¨μˆ˜ 객체만이 μ†Œμœ ν•˜λŠ” ν”„λ‘œν† νƒ€μž… ν”„λ‘œνΌν‹°κ°€ μ‘΄μž¬ν•©λ‹ˆλ‹€. μ΄λŠ” μƒμ„±μž ν•¨μˆ˜κ°€ 생성할 μΈμŠ€ν„΄μŠ€μ˜ ν”„λ‘œν† νƒ€μž…μ„ κ°€λ¦¬ν‚΅λ‹ˆλ‹€.

이것이 일반 객체와 ν•¨μˆ˜ 객체가 λ‹€λ₯Έ ν”„λ‘œν† νƒ€μž…μ„ κ°–λŠ” μ΄μœ μž…λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ μƒμ„±μž ν•¨μˆ˜λ‘œ ν˜ΈμΆœν•  수 μ—†λŠ” 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 ν”„λ‘œνΌν‹°λ₯Ό κ°–μŠ΅λ‹ˆλ‹€.

constructor ν”„λ‘œνΌν‹°λŠ” prototype ν”„λ‘œνΌν‹°λ‘œ μžμ‹ μ„ μ°Έμ‘°ν•˜κ³  μžˆλŠ” μƒμ„±μž ν•¨μˆ˜λ₯Ό 가리킀며, 이런 연결은 μƒμ„±μž ν•¨μˆ˜κ°€ 생성될 λ•Œμ— μ΄λ€„μ§‘λ‹ˆλ‹€.

  • ν”„λ‘œμ„ΈμŠ€λ‘œ μ΄ν•΄ν•΄λ³ΌκΉŒμš”?

    // μƒμ„±μž ν•¨μˆ˜
    function Human(name){
      this.name = name;
    }
    
    // μΈμŠ€ν„΄μŠ€ 생성
    const person = new Human('amy');
    
    console.log(person.constructor === Human);  // true
    1. Human μƒμ„±μž ν•¨μˆ˜λ‘œ person μ΄λΌλŠ” μΈμŠ€ν„΄μŠ€(객체)λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.
    2. person κ°μ²΄λŠ” constructorκ°€ μ—†μ§€λ§Œ Human.prototypeμ—λŠ” constructor ν”„λ‘œνΌν‹°κ°€ 있죠.
    3. λ”°λΌμ„œ 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 ν”„λ‘œνΌν‹°λ‘œ μ—°κ²°λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€. κ·Έλ ‡λ‹€λ©΄ μ΄λ ‡κ²Œ 생각할 수 있겠죠? λ¦¬ν„°λŸ΄μ— μ˜ν•΄ μƒμ„±λœ 객체도 μƒμ„±μž ν•¨μˆ˜λ‘œ μƒμ„±λ˜μž–μ•„?
    • μ„ΈλΆ€μ μœΌλ‘œλŠ” λ‹€λ₯΄μ§€λ§Œ, 큰 ν‹€μ—μ„œ 보면 κ°™μŠ΅λ‹ˆλ‹€. λ§žμ•„μš”, μ–΄λ €μš΄ λ§μž…λ‹ˆλ‹€. λ¦¬ν„°λŸ΄ ν‘œκΈ°λ²•μ— μ˜ν•΄ μƒμ„±λœ 객체도 상속을 μœ„ν•œ ν”„λ‘œν† νƒ€μž…μ΄ ν•„μš”ν•©λ‹ˆλ‹€. κ²°κ΅­ 가상적인 μƒμ„±μž ν•¨μˆ˜λ₯Ό κ°–κ²Œ λ˜λŠ” κ±°μ£ .

μžμ„Ένžˆ λ΄…μ‹œλ‹€. ν”„λ‘œν† νƒ€μž…μ€ μƒμ„±μž ν•¨μˆ˜κ°€ 생성될 λ•Œ 같이 μƒμ„±λ˜κ³ , prototypeκ³Ό constructor ν”„λ‘œνΌν‹°μ— μ˜ν•΄ μ—°κ²°λ˜μ£ ? κ·Έλ ‡λ‹€λŠ” 것은 ν”„λ‘œν† νƒ€μž…κ³Ό μƒμ„±μž ν•¨μˆ˜λŠ” 항상 쌍(pari)으둜 μ‘΄μž¬ν•œλ‹€λŠ” λœ»μž…λ‹ˆλ‹€.


잠깐 글이 κΈΈμ–΄μ§€λ―€λ‘œ λ‚΄λΆ€ λ™μž‘κ³Ό 좔상 연산에 λŒ€ν•΄ κΆκΈˆν•˜μ§€ μ•Šλ‹€λ©΄ λ„˜μ–΄κ°€μ„Έμš”.

좔상 μ—°μ‚°(Abstract Operation), ECMAScript μ‚¬μ–‘μ—μ„œ λ‚΄λΆ€ λ™μž‘ κ΅¬ν˜„ μ•Œκ³ λ¦¬μ¦˜μ„ ν‘œν˜„ν•œ κ²ƒμœΌλ‘œ ν•¨μˆ˜μ™€ μœ μ‚¬ν•œ μ˜μ‚¬ μ½”λ“œ(Pseudo Code)μž…λ‹ˆλ‹€.




μƒμ„±μž ν•¨μˆ˜λ‘œ μƒμ„±ν•œ 객체λ₯Ό ν‰κ°€ν•˜λŠ” 좔상 μ—°μ‚°



객체 μƒμ„±μž ν•¨μˆ˜

  1. κ³ μœ ν•œ 개체 %Object%μž…λ‹ˆλ‹€.
  2. μ „μ—­ 객체에 μ„ μ–Έλœ 객체 ν”„λ‘œνΌν‹°μ˜ 초기 κ°’μž…λ‹ˆλ‹€.
  3. μƒμ„±μžλ‘œ 호좜될 λ•Œ μƒˆλ‘œμš΄ 일반 객체λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.
  4. μƒμ„±μžκ°€ μ•„λ‹Œ ν•¨μˆ˜λ‘œ 호좜될 λ•Œ νƒ€μž… λ³€ν™˜μ„ μˆ˜ν–‰ν•©λ‹ˆλ‹€.
  5. ν•˜μœ„ λΆ„λ₯˜κ°€ κ°€λŠ₯ν•˜λ„λ‘ μ„€κ³„λ˜μ—ˆμŠ΅λ‹ˆλ‹€. 클래슀 μ •μ˜μ˜ 상속 κ°’μœΌλ‘œ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

Object ν•¨μˆ˜κ°€ 선택적 인수 κ°’μœΌλ‘œ 호좜되면 λ‹€μŒ 단계λ₯Ό μˆ˜ν–‰ν•©λ‹ˆλ‹€.

  1. NewTarget이 μ •μ˜λ˜μ§€ μ•Šμ•˜κ±°λ‚˜ ν™œμ„± ν•¨μˆ˜μΈ 경우
    1. λ°˜ν™˜ : OrdinaryCreateFromConstructor(NewTarget, "%Object.prototype%").
  2. 값이 μ •μ˜λ˜μ§€ μ•Šμ•˜κ±°λ‚˜ null인 경우
    1. λ°˜ν™˜ : OrdinaryObjectCreate("%Object.prototype%").
  3. κ·Έ μ™ΈλŠ” 값을 객체둜 λ§Œλ“€μ–΄ λ°˜ν™˜ν•©λ‹ˆλ‹€.
    • 개체 μƒμ„±μž ν•¨μˆ˜μ˜ "길이" 속성은 1μž…λ‹ˆλ‹€.

λ¦¬ν„°λŸ΄λ‘œ μƒμ„±ν•œ 객체λ₯Ό ν‰κ°€ν•˜λŠ” 좔상 μ—°μ‚°



빈 객체 λ¦¬ν„°λŸ΄

  1. λ°˜ν™˜ : OrdinaryObjectCreate("%Object.prototype%")

ν”„λ‘œνΌν‹°μ™€ ν•¨κ»˜ μ„ μ–Έλœ 객체 λ¦¬ν„°λŸ΄

  1. OrdinaryObjectCreate("%Object.prototype%")에 μ˜ν•΄ 빈 객체λ₯Ό 생성
  2. ν”„λ‘œνΌν‹° μ •μ˜ λ¦¬μŠ€νŠΈμ™€ ν”„λ‘œνΌν‹° μ •μ˜ 연산을 거친 ν›„ true인 인수 객체λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.
  3. 객체λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.



자, κΈ΄ 글이 λλ‚¬μŠ΅λ‹ˆλ‹€. μ •λ¦¬ν•˜μžλ©΄, λ¦¬ν„°λŸ΄μ— μ˜ν•΄ μƒμ„±λœ κ°μ²΄λŠ” μƒμ„±μž ν•¨μˆ˜μ— μ˜ν•΄ μƒμ„±λœ 객체가 μ•„λ‹ˆλ―€λ‘œ 생성 κ³Όμ •, μŠ€μ½”ν”„, ν΄λ‘œμ € λ“±μ˜ λ―Έλ¬˜ν•œ 차이가 μžˆμ§€λ§Œ μƒμ„±λœ κ°μ²΄λ‘œμ„œ λ™μΌν•œ νŠΉμ„±μ„ κ°–κ²Œ λ˜λ―€λ‘œ 본질적인 μ°¨μ΄λŠ” μ—†λ‹€λŠ” 것이 이 νŽ˜μ΄μ§€μ˜ κ²°λ‘ μž…λ‹ˆλ‹€.


ν”„λ‘œν† νƒ€μž… 생성 μ‹œμ 

λͺ¨λ“  κ°μ²΄λŠ” μƒμ„±μž ν•¨μˆ˜μ™€ μ—°κ²°λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.

λ‹€μ‹œ ν•œ 번 μ–ΈκΈ‰ν•˜μžλ©΄, ν”„λ‘œν† νƒ€μž…μ€ μƒμ„±μž ν•¨μˆ˜κ°€ μƒμ„±λ˜λŠ” μ‹œμ μ— 같이 μƒμ„±λ©λ‹ˆλ‹€.

μ‚¬μš©μž μ •μ˜ μƒμ„±μž ν•¨μˆ˜μ™€ ν”„λ‘œν† νƒ€μž… 생성 μ‹œμ 

μƒμ„±μž ν•¨μˆ˜λ‘œμ„œ ν˜ΈμΆœν•  수 μžˆλŠ” 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, 정리 쀑 μ‹λ³„λœ λ‚΄μš©μœΌλ‘œ μ™œ λ‹€λ₯Έμ§€ 이해해야 ν•  것

🧐 Google Chrome의 개발자 μ½˜μ†”μ—μ„œ [[Prototype]]이 좜λ ₯

의문점

  • λ‚΄λΆ€ μŠ¬λ‘―μ— 접근이 λΆˆκ°€λŠ₯ν•΄μ„œ __proto__λ₯Ό 톡해 μ ‘κ·Όν•œλ‹€κ³  ν–ˆλŠ”λ°, μ‹€μ œ ν¬λ‘œλ‹ˆμ›€ λΈŒλΌμš°μ €μ˜ 개발자 λ„κ΅¬μ—μ„œ κ°μ²΄λ‚˜ ν•¨μˆ˜λ₯Ό μ„ μ–Έν•˜κ³  μ‘°νšŒν•˜λ©΄ [[Prototype]]이 좜λ ₯λ˜λ„€μš”. μ–Έμ œ 바뀐 κ±ΈκΉŒμš”?

정리 된 λ‚΄μš©

TODO

  • μ°Έμ‘° Link

🧐 μ™œ __proto__λ₯Ό 직접 μ‚¬μš©ν•˜λŠ” 것을 κΈˆμ§€ν• κΉŒμš”?

의문점

  • __proto__λ₯Ό 직접 μ‚¬μš©ν•˜μ§€ 말라고 ν•˜λŠ”λ°, μ΄μœ λŠ” λ­˜κΉŒμš”?

정리 된 λ‚΄μš©

[[Prototype]] 객체의 변경은 μ΅œμ‹  μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진이 ν”„λ‘œνΌν‹° 접근을 μ΅œμ ν™”ν•˜λŠ” 방법에 따라 λͺ¨λ“  λΈŒλΌμš°μ €μ™€ μ—”μ§„μ—μ„œ 맀우 느리게 λ™μž‘ν•©λ‹ˆλ‹€.

λ˜ν•œ [[Prototype]]을 직접 λ³€κ²½ν•˜μ—¬ 객체의 상속이 μˆ˜μ •λ˜λŠ” obj.__proto__ = ...문은 λͺ¨λ“  μ½”λ“œκ°€ 접근이 κ°€λŠ₯ν•˜λ„λ‘ μ˜λ„μΉ˜ μ•Šκ²Œ ν™•μž₯될 수 있으며, μ΄λŠ” κ΄‘λ²”μœ„ν•˜κ²Œ μ„±λŠ₯의 μ €ν•˜λ₯Ό μΌμœΌν‚΅λ‹ˆλ‹€. 이런 λΆ€κ°€ 효과(Side Effect)λŠ” λ‹¨μˆœνžˆ λ¬Έ(statements)이 μ‹€ν–‰λ˜λŠ” λ•Œμ—λ§Œ κ·ΈμΉ˜μ§€ μ•Šκ³  μ§€μ†μ μœΌλ‘œ 영ν–₯을 미치게 되죠. λ”°λΌμ„œ μ„±λŠ₯을 ν–₯μƒμ‹œν‚€κ³  μ‹Άλ‹€λ©΄ 객체의 직접적인 [[Prototype]] 변경을 ν”Όν•΄μ•Ό ν•©λ‹ˆλ‹€.

λ¬Όλ‘  κ·Έ ν•΄κ²°μ±…μœΌλ‘œ λ§Žμ€ 방법이 있으며, κ·Έ 쀑 ν•˜λ‚˜μΈ Object.create()λ₯Ό μ‚¬μš©ν•΄ μ›ν•˜λŠ” ν”„λ‘œν† νƒ€μž… 객체λ₯Ό μƒˆλ‘œ 생성할 수 μžˆμŠ΅λ‹ˆλ‹€.



🧐 μ™œ 일반 객체의 ν”„λ‘œν† νƒ€μž…κ³Ό ν•¨μˆ˜ 객체의 ν”„λ‘œν† νƒ€μž…μ΄ κ΅¬λΆ„λ κΉŒμš”?

의문점

  • 뭐가 λ‹€λ₯Έ 건지 μ΄ν•΄λŠ” ν–ˆλŠ”λ°... μ™œ λ‹€λ₯Έ κ±ΈκΉŒμš”? μ„€λͺ…이 ν•„μš”ν•΄μš”.

정리 된 λ‚΄μš©

TODO


  • μ°Έμ‘° Link

🧐 μ™œ 객체 λ¦¬ν„°λŸ΄μ€ prototype을 가지지 μ•Šλ‚˜μš”?

의문점

  • 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κ°€ μŠ€ν„°λ””μ›κ³Ό 온라인 μŠ€ν„°λ”” μ§„ν–‰ν•˜λ©΄μ„œ μ˜λ¬Έμ μ„ κ°–κ³  ν•΄κ²°ν•œ λ‚΄μš©

βœ… ν”„λ‘œν† νƒ€μž… ꡐ체에 λŒ€ν•΄

의문점


정리 된 λ‚΄μš©

  • 정리해야함


βœ… Object.create λ©”μ„œλ“œκ°€ κ°–λŠ” 이점?

의문점


정리 된 λ‚΄μš©

  • 정리해야함


βœ… .prototypeκ³Ό .__proto__

의문점


정리 된 λ‚΄μš©

  • 정리해야함