본문으둜 κ±΄λ„ˆλ›°κΈ°

4. ν•¨μˆ˜μ™€ ν”„λ‘œν† νƒ€μž… 체이닝 - 3

이 글은 κ³ ν˜„μ€€, μ†‘ν˜•μ£Ό λ‹˜μ˜ μΈμ‚¬μ΄λ“œ μžλ°”μŠ€ν¬λ¦½νŠΈλ₯Όμ°Έμ‘°ν•˜μ—¬ μž‘μ„±ν•œ κΈ€μž…λ‹ˆλ‹€.

ν”„λ‘œν† νƒ€μž… 체이닝#

ν”„λ‘œν† νƒ€μž…μ˜ 두 가지 의미#

JSλŠ” C++μ΄λ‚˜ Java 같은 객체지ν–₯ 언어와 λ‹€λ₯Έ ν”„λ‘œν† νƒ€μž… 기반의 객체지ν–₯ ν”„λ‘œκ·Έλž˜λ°μ„ μ§€μ›ν•œλ‹€.

JSκ°€ μ–΄λ–»κ²Œ OOP κΈ°λŠ₯을 μ œκ³΅ν•˜λŠ”μ§€ μ΄ν•΄ν•˜λ €λ©΄, ν”„λ‘œν† νƒ€μž…κ³Ό ν”„λ‘œν† νƒ€μž… 체이닝에 λŒ€ν•΄ μ œλŒ€λ‘œ 이해해야 ν•œλ‹€.

Java와 같은 객체지ν–₯ ν”„λ‘œκ·Έλž˜λ°μ—μ„œλŠ” 클래슀λ₯Ό μ •μ˜ν•˜κ³  이λ₯Ό 톡해 객체λ₯Ό μƒμ„±ν•˜μ§€λ§Œ JSμ—λŠ” 클래슀 κ°œλ…μ΄ μ—†λ‹€. λŒ€μ‹ μ— 객체 λ¦¬ν„°λŸ΄μ΄λ‚˜, μƒμ„±μž ν•¨μˆ˜λ‘œ 객체λ₯Ό μƒμ„±ν•˜λŠ”λ°, μ΄λ ‡κ²Œ μƒμ„±λœ 객체의 λΆ€λͺ¨ 객체가 λ°”λ‘œ Prototype 객체닀. μžμ‹ κ°μ²΄λŠ” λΆ€λͺ¨ 객체가 가진 ν”„λ‘œνΌν‹° μ ‘κ·Όμ΄λ‚˜ λ©”μ†Œλ“œ 호좜이 κ°€λŠ₯ν•˜λ‹€.


☝️ 참고둜 졜근의 ES6 λ¬Έλ²•μ—μ„œλŠ” Class 문법이 μΆ”κ°€λ˜μ—ˆμœΌλ‚˜ μžλ°”μŠ€ν¬λ¦½νŠΈκ°€ 클래슀 기반으둜 λ°”λ€Œμ—ˆλ‹€λŠ” 것은 μ•„λ‹ˆλ‹€.


JS의 λͺ¨λ“  κ°μ²΄λŠ” μžμ‹ μ˜ λΆ€λͺ¨μΈ Prototype 객체λ₯Ό κ°€λ¦¬ν‚€λŠ” μˆ¨κ²¨μ§„ ν”„λ‘œνΌν‹°κ°€ μžˆλŠ”λ° ECMAScriptμ—μ„œλŠ” 이λ₯Ό 암묡적 ν”„λ‘œν†  νƒ€μž… 링크(Implicit prototype link)라고 λΆ€λ₯΄λ©° [[Prototype]] λΌλŠ” μˆ¨κ²¨μ§„ ν”„λ‘œνΌν‹°μ— μ €μž₯λœλ‹€. (ν¬λ‘¬μ΄λ‚˜ νŒŒμ΄μ–΄ν­μŠ€ 같은 λΈŒλΌμš°μ €μ—μ„œλŠ” 이λ₯Ό __proto__ ν”„λ‘œνΌν‹°λ‘œ λͺ…μ‹œμ μœΌλ‘œ μ œκ³΅ν•˜κ³  μžˆλ‹€.)

그런데 ν•¨μˆ˜ 객체가 κ°€μ§€λŠ” prototype ν”„λ‘œνΌν‹°μ™€ 객체의 μˆ¨μ€ ν”„λ‘œνΌν‹° [[Prototype]] 링크λ₯Ό ꡬ뢄해야 ν•œλ‹€. 이것이 λ°”λ‘œ ν—·κ°ˆλ¦¬κΈ° μ‰¬μš΄ ν”„λ‘œν† νƒ€μž…μ˜ 두 가지 μ˜λ―Έμ΄λ‹€.


prototype ν”„λ‘œνΌν‹°#

JSμ—μ„œ ν•¨μˆ˜λ₯Ό μ •μ˜ν•˜λ©΄, ν•¨μˆ˜ 생성과 λ™μ‹œμ— Prototype 객체 κ°€ μƒμ„±λœλ‹€. κ·Έλ¦¬κ³ μƒμ„±λœ ν•¨μˆ˜λŠ” prototype ν”„λ‘œνΌν‹°λ₯Ό 톡해 Prototype 객체λ₯Ό κ°€λ¦¬ν‚€κ²Œ λœλ‹€.

Prototype κ°μ²΄λŠ” 일반적인 객체와 κ°™μœΌλ©°, κΈ°λ³Έ μ†μ„±μœΌλ‘œ constructor 와 __proto__ λ₯Ό 가지고 μžˆλ‹€. 그리고 constructor 속성은 Prototype 객체와 ν•¨κ»˜μƒμ„±λ˜μ—ˆλ˜ ν•¨μˆ˜λ₯Ό 가리킨닀.

function myFunc() {}console.dir(myFunc);

[좜λ ₯ κ²°κ³Ό]

2020-03-05-4-ν•¨μˆ˜μ™€-ν”„λ‘œν† νƒ€μž…-체이닝-3-image-0


[[Prototype]] 링크( __proto__ )#

이 [[Prototype]] 링크 속성은 λͺ¨λ“  객체가 가지고 μžˆλŠ” 속성이닀. 이 속성은이 객체λ₯Ό μƒμ„±ν•œ μƒμ„±μž ν•¨μˆ˜μ˜ prototype ν”„λ‘œνΌν‹°κ°€ κ°€λ¦¬ν‚€λŠ” Prototype 객체λ₯Ό 가리킀고, 링크둜 μ—°κ²°ν•΄ μžμ‹ μ˜ λΆ€λͺ¨ 객체둜 μ„€μ •ν•œλ‹€.

// Person μƒμ„±μž ν•¨μˆ˜function Person(name) {    this.name = name;}
// foo 객체 생성var foo = new Person('foo');
console.dir(Person);console.dir(foo);

[좜λ ₯ κ²°κ³Ό]

2020-03-05-4-ν•¨μˆ˜μ™€-ν”„λ‘œν† νƒ€μž…-체이닝-3-image-1

κ²°κ³Όλ₯Ό 보면 Person() μƒμ„±μž ν•¨μˆ˜μ˜ prototype ν”„λ‘œνΌν‹°μ™€ foo 객체의 __proto__ ν”„λ‘œνΌν‹°κ°€ 같은 Prototype 객체λ₯Ό 가리킀고 μžˆλ‹€.

λ˜ν•œ ν•΄λ‹Ή Prototype κ°μ²΄λŠ” constructor() ν”„λ‘œνΌν‹°κ°€ Person() μƒμ„±μž ν•¨μˆ˜λ₯Όκ°€λ¦¬ν‚€κ³  μžˆλ‹€.


2020-03-05-4-ν•¨μˆ˜μ™€-ν”„λ‘œν† νƒ€μž…-체이닝-3-image-2


JS의 객체 생성 방식을 λ‹€μ‹œ ν•œλ²ˆ μ •λ¦¬ν•˜λ©΄ 이렇닀.

  1. μƒμ„±μž ν•¨μˆ˜( Person() )λ₯Ό μ •μ˜ν•˜λ©΄, ν•¨μˆ˜μ™€ λ™μ‹œμ— Prototype 객체( Person.prototype )이 μƒμ„±λœλ‹€.

  2. Person ν•¨μˆ˜μ˜ prototype ν”„λ‘œνΌν‹°λŠ” Person.prototype 을 가리킀고, Person.prototype.constructor κ°€ Person() ν•¨μˆ˜λ₯Ό 가리킨닀.

  3. Person() ν•¨μˆ˜λ‘œ μƒμ„±λœ 객체( foo )λŠ” Person() ν•¨μˆ˜μ˜ prototype ν”„λ‘œνΌν‹°κ°€ κ°€λ¦¬ν‚€λŠ” Prototype 객체λ₯Ό [[Prototype]] 링크둜 μ—°κ²°ν•œλ‹€. (__proto__ )


객체 λ¦¬ν„°λŸ΄ λ°©μ‹μœΌλ‘œ μƒμ„±λœ ν”„λ‘œν† νƒ€μž… 체이닝#

객체 λ¦¬ν„°λŸ΄ λ°©μ‹μœΌλ‘œ 객체λ₯Ό μƒμ„±ν•˜λŠ” 것도 κ²°κ΅­ λ‚΄λΆ€μ—μ„œλŠ” μƒμ„±μž ν•¨μˆ˜ Object() λ₯Ό μ‚¬μš©ν•˜λŠ” κ²ƒμž„μ„ κΈ°μ–΅ν•˜μž.

그리고 JSμ—μ„œ κ°μ²΄λŠ” 자기 μžμ‹ μ˜ ν”„λ‘œνΌν‹°λΏλ§Œ μ•„λ‹ˆλΌ, μžμ‹ μ˜ λΆ€λͺ¨ 역할을 ν•˜λŠ” Prototype 객체의 ν”„λ‘œνΌν‹°λ₯Ό μžμ‹ μ˜ κ²ƒμœΌλ‘œ μ ‘κ·Όν•˜λŠ” 것이 κ°€λŠ₯ν•˜λ‹€. 이λ₯Ό ν”„λ‘œν† νƒ€μž… 체이닝이라고 ν•œλ‹€.

var myObject = {    name: 'foo',    sayName: function () {        console.log('My Name is ' + this.name);    },};
myObject.sayName(); // My Name is fooconsole.log(myObject.hasOwnProperty('name')); // trueconsole.log(myObject.hasOwnProperty('nickName')); // falsemyObject.sayNickName(); // Uncaught TypeError: Object #<Object> has no method 'sayNickName'

myObject λŠ” name ν”„λ‘œνΌν‹°μ™€ sayName() λ©”μ†Œλ“œλ₯Ό 가진 객체이닀. sayName() λ©”μ†Œλ“œλŠ” μ œλŒ€λ‘œ 좜λ ₯λ˜μ§€λ§Œ, sayNickName() λ©”μ†Œλ“œλŠ” myObject 의 λ©”μ†Œλ“œκ°€ μ•„λ‹ˆλ―€λ‘œ μ—λŸ¬κ°€ λ°œμƒν•œλ‹€.

그런데 myObject μ—λŠ” hasOwnProperty() λΌλŠ” λ©”μ†Œλ“œκ°€ μ—†μŒμ—λ„ κ²°κ³Όκ°€ μ •μƒμ μœΌλ‘œ 좜λ ₯됐닀.

μ΄μœ λŠ” λ‹€μŒκ³Ό κ°™λ‹€.

  1. 객체 λ¦¬ν„°λŸ΄λ‘œ μƒμ„±λœ 객체도 λ‚΄μž₯ μƒμ„±μž ν•¨μˆ˜ Object() λ₯Ό 톡해 μƒμ„±λœ 것이닀 .

  2. μƒμ„±μž ν•¨μˆ˜ Object() μ—­μ‹œ ν•¨μˆ˜ κ°μ²΄μ΄λ―€λ‘œ prototype ν”„λ‘œνΌν‹°λ₯Ό κ°–κ³  있고, Object.prototype 객체λ₯Ό 가리킀고 μžˆλ‹€.

  3. μƒμ„±μž ν•¨μˆ˜ Object() λ₯Ό 톡해 μƒμ„±λœ myObject κ°μ²΄λŠ” Object() ν•¨μˆ˜μ˜ prototype ν”„λ‘œνΌν‹°κ°€ κ°€λ¦¬ν‚€λŠ” Object.prototype 객체λ₯Ό [[Prototype]] 링크둜 μ—°κ²°ν•œλ‹€.

  4. JSμ—μ„œ νŠΉμ • 객체의 ν”„λ‘œνΌν‹°λ‚˜ λ©”μ†Œλ“œμ— μ ‘κ·Όν•˜λ €κ³  ν•  λ•Œ, μ ‘κ·Όν•˜λ €λŠ” ν”„λ‘œνΌν‹°λ˜λŠ” λ©”μ†Œλ“œκ°€ μ—†λ‹€λ©΄, [[Prototype]] 링크λ₯Ό 따라 μžμ‹ μ˜ λΆ€λͺ¨ 역할을 ν•˜λŠ” Prototype 객체의 ν”„λ‘œνΌν‹° λ˜λŠ” λ©”μ†Œλ“œλ₯Ό μ°¨λ‘€λŒ€λ‘œ κ²€μƒ‰ν•œλ‹€. (이λ₯Ό ν”„λ‘œν† νƒ€μž… 체이닝이라고 ν•œλ‹€.)

  5. Object.prototype κ°μ²΄λŠ” λͺ¨λ“  객체의 쑰상 역할을 ν•˜λŠ” κ°μ²΄λ‘œμ„œ, toString() , hasOwnProperty() λ“±μ˜ ν‘œμ€€ λ©”μ†Œλ“œλ₯Ό κ°–κ³  μžˆμœΌλ―€λ‘œ, 이λ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€.


2020-03-05-4-ν•¨μˆ˜μ™€-ν”„λ‘œν† νƒ€μž…-체이닝-3-image-3


μƒμ„±μž ν•¨μˆ˜λ‘œ μƒμ„±λœ 객체의 ν”„λ‘œν† νƒ€μž… 체이닝#

그러면 객체 λ¦¬ν„°λŸ΄ 방식이 μ•„λ‹Œ, 직접 μ •μ˜ν•œ μƒμ„±μž ν•¨μˆ˜λ‘œ 객체λ₯Ό μƒμ„±ν•˜λŠ” κ²½μš°μ–΄λ–»κ²Œ ν”„λ‘œν† νƒ€μž… 체이닝이 λ™μž‘ν•˜λŠ”μ§€ μ•Œμ•„λ³΄μž.

// Person() μƒμ„±μž ν•¨μˆ˜function Person(name, age, hobby) {    this.name = name;    this.age = age;    this.hobby = hobby;}
// foo 객체 생성var foo = new Person('foo', 30, 'tennis');
// ν”„λ‘œν† νƒ€μž… 체이닝console.log(foo.hasOwnProperty('name')); // true
// Person.prototype 객체 좜λ ₯console.dir(Person.prototype);

μœ„μ˜ μ˜ˆμ œμ—μ„œ foo 객체의 μƒμ„±μžλŠ” Person() ν•¨μˆ˜μ΄λ‹€. λ”°λΌμ„œ foo 객체의 Prototype κ°μ²΄λŠ” μžμ‹ μ„ μƒμ„±ν•œ Person() ν•¨μˆ˜μ˜ prototype ν”„λ‘œνΌν‹°κ°€ κ°€λ¦¬ν‚€λŠ” 객체( Person.prototype )κ°€ λœλ‹€.

그런데 μ–΄λ–»κ²Œ Object.prototype 객체가 κ°–κ³  μžˆλŠ” ν‘œμ€€ λ©”μ†Œλ“œμΈ hasOwnProperty() λ₯Ό μ‚¬μš©ν•  수 μžˆμ—ˆμ„κΉŒ?

  1. foo.hasOwnProperty() λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν–ˆμ„ λ•Œ foo κ°μ²΄μ—λŠ” foo.hasOwnProperty() λ©”μ†Œλ“œκ°€ μ—†κΈ° λ•Œλ¬Έμ— ν”„λ‘œν† νƒ€μž… μ²΄μ΄λ‹μœΌλ‘œ λΆ€λͺ¨ 객체인 Person.prototype μ—μ„œ hasOwnProperty() λ©”μ†Œλ“œλ₯Ό μ°ΎλŠ”λ‹€.

  2. ν•˜μ§€λ§Œ, Person.prototype κ°μ²΄λŠ” λ””ν΄νŠΈλ‘œ constructor ν”„λ‘œνΌν‹°λ§Œμ„ κ°–κ³  μžˆμœΌλ―€λ‘œ hasOwnProperty() λ©”μ†Œλ“œκ°€ μ—†λ‹€.

  3. Person.prototype 객체 μ—­μ‹œ JS 객체둜, λͺ¨λ“  객체의 λΆ€λͺ¨μΈ Object.prototype 을 Prototype 객체둜 가진닀. λ”°λΌμ„œ, Object.prototype μ—μ„œ hasOwnProperty() λ₯Ό λ‹€μ‹œ κ²€μƒ‰ν•˜λŠ” ν”„λ‘œν† νƒ€μž… 체이닝이 ν•œλ²ˆ 더 μΌμ–΄λ‚˜κ³ , ν‘œμ€€ λ©”μ†Œλ“œλ“€μ„ μ‚¬μš©ν•  수 μžˆλ‹€.


2020-03-05-4-ν•¨μˆ˜μ™€-ν”„λ‘œν† νƒ€μž…-체이닝-3-image-4


μ΄λ ‡κ²Œ 객체 λ¦¬ν„°λŸ΄ 방식과 직접 μ •μ˜ν•œ μƒμ„±μž ν•¨μˆ˜μ—μ„œμ˜ ν”„λ‘œν† νƒ€μž… 체이닝 λ°©λ²•μ—μ„œ 쑰금 차이가 μžˆμ§€λ§Œ κ²°κ΅­ 원칙은 κ°™λ‹€.


"μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ λͺ¨λ“  κ°μ²΄λŠ” μžμ‹ μ„ μƒμ„±ν•œ μƒμ„±μž ν•¨μˆ˜μ˜ prototype ν”„λ‘œνΌν‹°κ°€ κ°€λ¦¬ν‚€λŠ” 객체λ₯Ό μžμ‹ μ˜ Prototype 객체(λΆ€λͺ¨ 객체)둜 μ·¨κΈ‰ν•œλ‹€."


ν”„λ‘œν† νƒ€μž… μ²΄μ΄λ‹μ˜ 쒅점#

μ•žμ„œ μ‚΄νŽ΄λ³Έ κ²ƒμ²˜λŸΌ, Object.prototype κ°μ²΄λŠ” ν”„λ‘œν† νƒ€μž… μ²΄μ΄λ‹μ˜ 쒅점이닀. 방식에 상관 없이 λͺ¨λ“  κ°μ²΄λŠ” ν”„λ‘œν† νƒ€μž… μ²΄μ΄λ‹μœΌλ‘œ Object.prototype 객체가 가진 ν”„λ‘œνΌν‹°μ™€ λ©”μ†Œλ“œμ— μ ‘κ·Ό κ°€λŠ₯ν•˜κ³  μ„œλ‘œ 곡유 κ°€λŠ₯ν•˜λ‹€.


κΈ°λ³Έ 데이터 νƒ€μž… ν™•μž₯#

JS의 숫자, λ¬Έμžμ—΄, λ°°μ—΄ λ“±μ—μ„œ μ‚¬μš©ν•˜λŠ” ν‘œμ€€ λ©”μ†Œλ“œλ“€μ˜ 경우 μ΄λ“€μ˜ ν”„λ‘œν† νƒ€μž…μΈ Number.prototype , String.prototype , Array.prototype 에 μ •μ˜λ˜μ–΄ μžˆλ‹€. λ˜ν•œ 이듀 μ—­μ‹œ Object.prototype 을 μžμ‹ μ˜ ν”„λ‘œν† νƒ€μž…μœΌλ‘œ κ°–κ³  μžˆμ–΄μ„œ Object.prototype 의 λ©”μ†Œλ“œ μ—­μ‹œ μ‚¬μš©ν•  수 μžˆλ‹€.

λ˜ν•œ JSλŠ” ν‘œμ€€ 빌트인 Prototype 객체에 μ‚¬μš©μžκ°€ 직접 λ©”μ†Œλ“œλ₯Ό μ •μ˜ν•΄ μΆ”κ°€ν•˜λŠ”κ²ƒμ„ ν—ˆμš©ν•œλ‹€.

String.prototype.testMethod = function () {    console.log('This is the String.prototype.testMethod()');};
var str = 'This is test';str.testMethod();
console.dir(String.prototype);

[좜λ ₯ κ²°κ³Ό]

2020-03-05-4-ν•¨μˆ˜μ™€-ν”„λ‘œν† νƒ€μž…-체이닝-3-image-5


2020-03-05-4-ν•¨μˆ˜μ™€-ν”„λ‘œν† νƒ€μž…-체이닝-3-image-6


ν”„λ‘œν† νƒ€μž…λ„ μžλ°”μŠ€ν¬λ¦½νŠΈ 객체닀#

ν•¨μˆ˜κ°€ 생성될 λ•Œ, μžμ‹ μ˜ prototype ν”„λ‘œνΌν‹°μ— μ—°κ²°λ˜λŠ” Prototype κ°μ²΄λŠ” λ””ν΄νŠΈλ‘œ constructor ν”„λ‘œνΌν‹°λ§Œμ„ 가진 객체닀. λ‹€μ‹œ 말해 Prototype 객체 μ—­μ‹œ μžλ°”μŠ€ν¬λ¦½νŠΈ 객체이닀.

즉, 일반 객체처럼 동적 ν”„λ‘œνΌν‹° μΆ”κ°€/μ‚­μ œκ°€ κ°€λŠ₯ν•˜λ‹€. μ΄λ ‡κ²Œ λ³€κ²½λœ ν”„λ‘œνΌν‹°λŠ”μ‹€μ‹œκ°„μœΌλ‘œ ν”„λ‘œν† νƒ€μž… 체이닝에 λ°˜μ˜λœλ‹€.

// Person μƒμ„±μž ν•¨μˆ˜function Person(name) {    this.name = name;}
// foo 객체 생성var foo = new Person('foo');
// foo.sayHello();// 이 μ‹œμ μ—λŠ” sayHello() λ©”μ†Œλ“œκ°€ foo 객체와 Person.prototype 객체 λͺ¨λ‘μ— μ •μ˜λ˜μ–΄ μžˆμ§€ μ•ŠμœΌλ―€λ‘œ μ—λŸ¬κ°€ λ°œμƒν•œλ‹€.
// Prototype 객체에 sayHello() λ©”μ†Œλ“œ μ •μ˜Person.prototype.sayHello = function () {    console.log('Hello');};
foo.sayHello(); // Hello

foo 객체의 Prototype 객체인 Person.prototype 객체에 λ™μ μœΌλ‘œ sayHello() λ©”μ†Œλ“œλ₯Ό μΆ”κ°€ν•œ μ΄ν›„μ—λŠ” foo 객체에 sayHello() λ©”μ†Œλ“œκ°€ μ—†μ§€λ§Œ ν”„λ‘œν† νƒ€μž… μ²΄μ΄λ‹μœΌλ‘œ 'Hello' κ°€ 좜λ ₯λœλ‹€.


ν”„λ‘œν† νƒ€μž… λ©”μ†Œλ“œμ™€ this 바인딩#

Prototype κ°μ²΄λŠ” λ©”μ†Œλ“œλ₯Ό κ°€μ§ˆ 수 μžˆλ‹€. (이λ₯Ό 짧게 ν”„λ‘œν† νƒ€μž… λ©”μ†Œλ“œλΌκ³ λΆ€λ₯΄κΈ°λ„ 함.)

λ§Œμ•½ ν”„λ‘œν† νƒ€μž… λ©”μ†Œλ“œ λ‚΄λΆ€μ—μ„œ this λ₯Ό μ‚¬μš©ν•œλ‹€λ©΄ μ΄λŠ” 어디에 바인딩될 것인가 ?

μ΄λŠ” μ•žμ„œ μ‚΄νŽ΄λ³Έ 객체의 λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•  λ•Œ this 바인딩 κ·œμΉ™κ³Ό λ™μΌν•˜λ‹€. 즉 this κ°€ λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•œ 객체에 λ°”μΈλ”©λœλ‹€.

// Person() μƒμ„±μž ν•¨μˆ˜function Person(name) {    this.name = name;}
// getName() ν”„λ‘œν† νƒ€μž… λ©”μ†Œλ“œPerson.prototype.getName = function () {    return this.name;};
// foo 객체 생성var foo = new Person('foo');
console.log(foo.getName()); // foo
// Person.prototype 객체에 name ν”„λ‘œνΌν‹° 동적 μΆ”κ°€Person.prototype.name = 'person';
console.log(Person.prototype.getName()); // person

λ””ν΄νŠΈ ν”„λ‘œν† νƒ€μž…μ€ λ‹€λ₯Έ 객체둜 변경이 κ°€λŠ₯ν•˜λ‹€#

μ•žμ—μ„œ μ‚΄νŽ΄λ³Έ κ²ƒμ²˜λŸΌ JSμ—μ„œλŠ” ν•¨μˆ˜λ₯Ό μ •μ˜ν•  λ•Œ, ν•¨μˆ˜ 생성과 λ™μ‹œμ— Prototype 객체가 μƒμ„±λ˜κ³ , μƒμ„±λœ ν•¨μˆ˜μ˜ prototype ν”„λ‘œνΌν‹°κ°€ Prototype 객체λ₯Ό 가리킨닀.

이 ν•¨μˆ˜ 생성과 λ™μ‹œμ— μƒμ„±λ˜λŠ” Prototype 객체λ₯Ό λ””ν΄νŠΈ ν”„λ‘œν† νƒ€μž…μ΄λΌκ³  ν•œλ‹€. 그런데, 이 λ””ν΄νŠΈ ν”„λ‘œν† νƒ€μž… 객체λ₯Ό λ‹€λ₯Έ 일반 객체둜 λ³€κ²½ν•˜λŠ” 것이 κ°€λŠ₯ν•˜λ‹€.

// Person() μƒμ„±μž ν•¨μˆ˜function Person(name) {    this.name = name;}console.log(Person.prototype.constructor);
// foo 객체 생성var foo = new Person('foo');console.log(foo.country);
// λ””ν΄νŠΈ ν”„λ‘œν† νƒ€μž… 객체 λ³€κ²½Person.prototype = {    country: 'korea',};console.log(Person.prototype.constructor);
// bar 객체 생성var bar = new Person('bar');console.log(foo.country);console.log(bar.country);console.log(foo.constructor);console.log(bar.constructor);

[좜λ ₯ κ²°κ³Ό]

2020-03-05-4-ν•¨μˆ˜μ™€-ν”„λ‘œν† νƒ€μž…-체이닝-3-image-7

그런데 μ£Όμ˜ν•΄μ•Όν•  점이 μžˆλŠ”λ°, μƒμ„±μž ν•¨μˆ˜μ˜ prototype ν”„λ‘œνΌν‹°λ₯Ό λ‹€λ₯Έ 일반 객체둜 λ³€κ²½ν•˜λ©΄, λ³€κ²½ν•œ 이후에 μƒμ„±λœ 객체듀은 λ³€κ²½λœ Prototype 객체둜 [[Prototype]] 링크λ₯Ό μ—°κ²°ν•œμ§€λ§Œ, 이전에 μƒμ„±λœ 객체듀은 κΈ°μ‘΄ Prototype 객체둜 [[Prototype]] 링크λ₯Ό μœ μ§€ν•œλ‹€.


2020-03-05-4-ν•¨μˆ˜μ™€-ν”„λ‘œν† νƒ€μž…-체이닝-3-image-8



객체의 ν”„λ‘œνΌν‹° μ½κΈ°λ‚˜ λ©”μ†Œλ“œλ₯Ό μ‹€ν–‰ν•  λ•Œλ§Œ ν”„λ‘œν† νƒ€μž… 체이닝이 λ™μž‘ν•œλ‹€#

ν”„λ‘œν† νƒ€μž… 체이닝은 객체의 ν”„λ‘œνΌν‹°λ₯Ό μ½μœΌλ €κ³ ν•  λ•Œ, λ©”μ†Œλ“œλ₯Ό μ‹€ν–‰ν•  λ•Œλ§Œ λ™μž‘ν•˜κ³  λ°˜λŒ€λ‘œ 객체에 μžˆλŠ” νŠΉμ • ν”„λ‘œνΌν‹°μ— 값을 μ“°λ €κ³  ν•  λ•ŒλŠ” ν”„λ‘œν† νƒ€μž… 체이닝이 μΌμ–΄λ‚˜μ§€ μ•ŠλŠ”λ‹€. 객체에 μ—†λŠ” ν”„λ‘œνΌν‹°μ— 값을 μ“°λ €κ³  ν•  κ²½μš°μ—λŠ” λ™μ μœΌλ‘œ 객체에 ν”„λ‘œνΌν‹°λ₯Ό μΆ”κ°€ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€.

// Person() μƒμ„±μž ν•¨μˆ˜function Person(name) {    this.name = name;}
Person.prototype.country = 'Korea';
var foo = new Person('foo');var bar = new Person('bar');console.log(foo.country); // Koreaconsole.log(bar.country); // Korea
foo.country = 'USA';
console.log(foo.country); // USAconsole.log(bar.country); // Korea

foo.country λ₯Ό 'USA'둜 μˆ˜μ •ν•˜μ˜€μ§€λ§Œ, bar.country λŠ” κ·ΈλŒ€λ‘œ 'Korea'인데, μ΄λŠ” Person.prototype.country κ°€ μˆ˜μ •λ˜μ§€ μ•Šμ•˜κΈ° λ•Œλ¬Έμ΄λ‹€.


참고자료#

πŸ”— [Javascript ] ν”„λ‘œν† νƒ€μž… μ΄ν•΄ν•˜κΈ°

πŸ”— Javascript 기초 - Object prototype μ΄ν•΄ν•˜κΈ°