πŸ’ƒν”„λ‘œν† νƒ€μž…μ˜ λ™μž‘λ°©μ‹, (__proto__, overide, channing)

junameeΒ·2021λ…„ 7μ›” 25일
0

μžλ°”μŠ€ν¬λ¦½νŠΈ

λͺ©λ‘ 보기
2/11

prototype 의 λ™μž‘λ°©μ‹

prototype은 μƒμ„±μž ν•¨μˆ˜ λ‚΄λΆ€μ˜ property이닀. 이 ν”„λ‘œν† νƒ€μž…μ€ μƒμ„±μž ν•¨μˆ˜λ₯Ό 톡해 λ§Œλ“  객체, μΈμŠ€ν„΄μŠ€κ°€ μ‚¬μš©ν•  λ©”μ„œλ“œλ₯Ό μ €μž₯ν•˜κ³  μžˆλ‹€. μƒμ„±μžν•¨μˆ˜λ₯Ό 톡해 μΈμŠ€ν„΄μŠ€λ₯Ό λ§Œλ“€λ©΄ μΈμŠ€ν„΄μŠ€ 내뢀에 μžλ™μœΌλ‘œ__proto__κ°€ ν”„λ‘œνΌν‹°λ‘œ μƒμ„±λ˜λŠ”λ° 이 ν”„λ‘œνΌν‹°λŠ” μΈμŠ€ν„΄μŠ€κ°€ μ‚¬μš©ν•  λ©”μ†Œλ“œ, 즉 μƒμ„±μž ν•¨μˆ˜μ˜ prototype을 μ°Έμ‘°ν•œλ‹€. μ΄λŠ” μƒλž΅μ΄ κ°€λŠ₯ν•˜λ„λ‘ ν‘œν˜„ν•  수 μžˆμ–΄ 마치 μƒμ„±μžν•¨μˆ˜μ˜ ν”„λ‘œν† νƒ€μž…μ„ μžμ‹ μ˜ ν”„λ‘œνΌν‹°μΈ κ²ƒλ§ˆλƒ₯ μ‚¬μš©ν•  수 있게 λœλ‹€. λ˜ν•œ, λ©”μ„œλ“œμ˜€λ²„λΌμ΄λ“œ 속성 λ•Œλ¬Έμ— μƒμ„±μžν•¨μˆ˜μ˜ λ©”μ„œλ“œλŠ” μžμ‹ μ˜ λ©”μ„œλ“œ μƒνƒœλŠ” μœ μ§€ν•˜λ©΄μ„œλ„ μΈμŠ€ν„΄μŠ€λ³„λ‘œ 재 μ •μ˜ν•  수 μžˆμ–΄ 상황에 맞게 μ»€μŠ€ν…€ν•˜μ—¬ μ‚¬μš©ν•  수 μžˆλ‹€. λ•Œλ¬Έμ— μΈμŠ€ν„΄μŠ€μ˜ λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•˜λ©΄ λ¨Όμ € μΈμŠ€ν„΄μŠ€μ— ν•΄λ‹Ή λ©”μ†Œλ“œκ°€ ν”„λ‘œνΌν‹°μ— ν¬ν•¨λ˜μ–΄μžˆλŠ”μ§€λ₯Ό νŒŒμ•…ν•˜κ³ , μ—†λ‹€λ©΄ ν”„λ‘œνΌν‹° 체이닝 μ†μ„±μœΌλ‘œ __proto__λ₯Ό 톡해 μƒμ„±μžν•¨μˆ˜μ˜ λ©”μ„œλ“œλ₯Ό μ‹€ν–‰ν•˜κ²Œ λœλ‹€.


μƒλž΅κ°€λŠ₯ν•œ __proto__

var Person = function(name){
    this._name=name
   } 
   
Person.prototype.getName=function(){
    console.log(this)
    return 'My name is '+this._name
}

const guest1=new Person('namju')

Personμ΄λΌλŠ” μƒμ„±μžν•¨μˆ˜λ₯Ό 톡해 guest1μ΄λΌλŠ” μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜μ˜€λ‹€.
λ‹€μŒλΆ€ν„° 비ꡐ해보면

guest1.getName()

//this: 
  Person {_name: "namju"}_name: "namju"[[Prototype]]: Object
//return:
  "My name is namju"
  
guest1.__proto__.getName()
//this:
  {getName: Ζ’, constructor: Ζ’}
//return: "My name is undefined"

μΈμŠ€ν„΄μŠ€μ—μ„œ λ°”λ‘œ λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•˜λ©΄ 이름이 μ œλŒ€λ‘œ λ‚˜μ˜€κ³ 
μΈμŠ€ν„΄μŠ€μ˜ ν”„λ‘œν† λ‘œ μ ‘κ·Όν•˜λ©΄ undefinedκ°€ λ°˜ν™˜λ˜μ—ˆλ‹€.
μ΄λŠ” λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•  λ•Œ, λ©”μ†Œλ“œ μ•žμ—μžˆλŠ” 객체λ₯Ό this둜 μ§€μ •ν•˜κΈ° λ•Œλ¬Έμ— 값이 μ˜λ„ν•œλŒ€λ‘œ λ‚˜μ˜€μ§€ λͺ»ν–ˆλŠ”데,

guest1.getName()μ—μ„œμ˜ thisλŠ” guest1 μ΄μ–΄μ„œ guest1._name을 뢈러올 수 μžˆμ—ˆκ³ 
guest1.__proto__.getName()μ—μ„œμ˜ thisλŠ” guest1.__proto__인데 μ΄λŠ” Person.prototypeκ³Ό λ™μΌν•˜λ‹€.
Person.prototype = {getName: Ζ’, constructor: Ζ’}μ—μ„œλŠ” _nameμ΄λΌλŠ” 속성을 찾을 수 μ—†κΈ° λ•Œλ¬Έμ— undefinedλ₯Ό λ°˜ν™˜ ν•œ 것이닀.

λ•Œλ¬Έμ— μΈμŠ€ν„΄μŠ€μ˜ __proto__κ°€ μƒμ„±μžν•¨μˆ˜μ˜ prototype을 μ°Έμ‘°ν•œλ‹€κ³  ν•˜μ—¬λ„ thisλ₯Ό μΈμŠ€ν„΄μŠ€λ‘œ μ§€μ •ν•˜μ—¬ μ‹€ν–‰ν•  λ•Œμ—” __proto__λ₯Ό μƒλž΅ν•˜κ³  ν˜ΈμΆœν•΄μ•Ό ν•œλ‹€.

즉, μƒμ„±μž ν•¨μˆ˜μ˜ prototype의 λ©”μ„œλ“œ, ν”„λ‘œνΌν‹°λŠ” μΈμŠ€ν„΄μŠ€μ—μ„œλ„ μžμ‹ μ˜ λ©”μ†Œλ“œ, ν”„λ‘œνΌν‹°μΈ κ²ƒμ²˜λŸΌ μ ‘κ·Όν•˜μ—¬ μ‚¬μš©ν•  수 μžˆλ‹€.


λ©”μ„œλ“œ μ˜€λ²„λΌμ΄λ“œ

만일, μΈμŠ€ν„΄μŠ€κ°€ λ™μΌν•œ μ΄λ¦„μ˜ ν”„λ‘œνΌν‹°λ‚˜ λ©”μ„œλ“œλ₯Ό κ°–κ²Œλœλ‹€λ©΄ μ–΄λ–»κ²Œ 될까, μ•„λž˜μ˜ μ˜ˆμ‹œλŠ” μƒμ„±μžν•¨μˆ˜μ— singμ΄λΌλŠ” λ©”μ„œλ“œλ₯Ό λΆ€μ—¬ν•˜κ³ , μΈμŠ€ν„΄μŠ€μ— λ˜‘κ°™μ΄ singμ΄λΌλŠ” λ©”μ„œλ“œλ₯Ό μΆ”κ°€ ν•˜λŠ” μ½”λ“œμ΄λ‹€.

var Singer = function(song){
    this.song=song
    }
    
Singer.prototype.sing = function(){
    console.log(this)
    return this.song+'라라라~'
}

const iu = new Singer('λ‚΄μ†μ„μž‘μ•„ ')
const biber = new Singer('peaches ')

iu.sing = function(){
	console.log(this)
    return '였늘의 λ…Έλž˜λŠ” '+this.song
    }
    
iu.sing()
// "였늘의 λ…Έλž˜λŠ” λ‚΄μ†μ„μž‘μ•„ "
biber.sing()
// "peaches 라라라~"

λ©”μ„œλ“œλ₯Ό μƒˆλ‘œ μ •μ˜ν•œ μΈμŠ€ν„΄μŠ€(iu)μ—μ„œλŠ” μƒμ„±μžν•¨μˆ˜μ—μ„œ μ •ν•œ λ©”μ†Œλ“œ κ²°κ³Ό(this.song+라라라)κ°€ μ•„λ‹Œ μΈμŠ€ν„΄μŠ€μ—μ„œ μ§€μ •ν•œ λ©”μ†Œλ“œλ‘œ λ³€κ²½λ˜μ–΄ μ‹€ν–‰λ˜μ—ˆκ³ , iu와 biber의 κ²°κ³Όλ₯Ό 비ꡐ해보면 기쑴의 λ©”μ„œλ“œκ°€ 사라진 것은 μ•„λ‹ˆλž€ κ±Έ 확인할 수 μžˆλ‹€.

즉 기쑴의 λ©”μ„œλ“œλ₯Ό μ—†μ• λ©΄μ„œ μƒˆλ‘œμš΄ λ©”μ„œλ“œλ‘œ λ³€κ²½ν•œ 것이 μ•„λ‹Œ 원본은 μœ μ§€λ˜κ³  μžˆλŠ” μƒνƒœμ—μ„œ λ‹€λ₯Έ λ©”μ„œλ“œλ₯Ό 얹은 κ°œλ…μ΄λ‹€.
이것을 'λ©”μ†Œλ“œ μ˜€λ²„λΌμ΄λ”©' 이라고 ν•œλ‹€

λ‹€λ₯΄κ²Œ ν‘œν˜„ν•˜λ©΄ 각 μΈμŠ€ν„΄μŠ€ λ³„λ‘œ μ»€μŠ€ν…€ν™”ν•œ λ©”μ„œλ“œλ₯Ό μ‹€ν–‰μ‹œν‚¬ 수 μžˆλŠ” μž₯점이닀.

λ©”μ„œλ“œκ°€ μ˜€λ²„λΌμ΄λ“œ 된 것이기 λ•Œλ¬Έμ— μΈμŠ€ν„΄μŠ€μ˜ __proto__둜 μš°νšŒν•˜λ©΄ λ‹€μ‹œ μƒμ„±μžν•¨μˆ˜μ˜ λ©”μ„œλ“œμ— μ ‘κ·Όν•  수 μžˆλ‹€.

iu.sing()  //"였늘의 λ…Έλž˜λŠ” λ‚΄μ†μ„μž‘μ•„ "
iu.__proto__.sing() //undefined 라라라

μœ„μ™€ 같은 λ°©λ²•μœΌλ‘œ sing λ©”μ„œλ“œλ₯Ό μ‹€ν–‰μ‹œμΌœλ³΄λ©΄ this의 차이에 따라 song을 λ°˜ν™˜ν•˜κ±°λ‚˜ undefinedλ₯Ό λ°˜ν™˜ν•œλ‹€.(iu.__proto__
μ—λŠ” song ν”„λ‘œνΌν‹°κ°€ μ—†μœΌλ―€λ‘œ undefined)

그럼 songμ΄λΌλŠ” ν”„λ‘œνΌν‹°λ₯Ό λ§Œλ“€μ–΄μ£Όλ©΄ μ˜¬λ°”λ₯Έ 값을 λ°˜ν™˜ν•  수 μžˆμ„ 것인데, callμ΄λ‚˜ apply둜 thisλ₯Ό 지정해주어 thisλ₯Ό μ›ν•˜λŠ” μΈμŠ€ν„΄μŠ€λ‘œ λ°”κΏ” 쀄 수 μžˆλ‹€.

iu.__proto__.song = 'μŠ€λ¬Όμ…‹'
iu.__proto__.sing.call(iu)
//μŠ€λ¬Όμ…‹ 라라라

처음의 μƒμ„±μžν•¨μˆ˜μ˜ λ©”μ„œλ“œλ‘œ 싀행을 μ‹œμΌ°λ‹€.


Singer {song: "λ‚΄μ†μ„μž‘μ•„"}
  song: "λ‚΄μ†μ„μž‘μ•„"
  [[Prototype]]: Object
     sing: Ζ’ ()
     song: "μŠ€λ¬Όμ…‹ "
     constructor: Ζ’ (song)
     [[Prototype]]: Object
     

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

μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진이 singμ΄λΌλŠ” λ©”μ„œλ“œλ₯Ό μ°ΎλŠ” 방식은 ν˜ΈμΆœν•œ μžμ‹ μœΌλ‘œλΆ€ν„° κ°€μž₯ κ°€κΉŒμš΄ ν”„λ‘œνΌν‹° μ€‘μ—μ„œ λ©”μ„œλ“œλ₯Ό μ°ΎλŠ” 것이닀. 있으면 λ°˜ν™˜ν•˜κ³ , μ—†μœΌλ©΄__proto__λ₯Ό κ²€μƒ‰ν•˜μ—¬ λ©”μ„œλ“œλ₯Ό μ°ΎλŠ”λ‹€. 이 처럼 __proto__ ν”„λ‘œνΌν‹°κ°€ μ—°μ‡„μ μœΌλ‘œ μ΄μ–΄μ§€λŠ” 것을 ν”„λ‘œν† νƒ€μž… μ²΄μΈμ΄λΌν•˜κ³ , 체인을 따라가며 κ²€μƒ‰ν•˜λŠ” 것을 ν”„λ‘œν† νƒ€μž… 체이닝이라고 ν•œλ‹€.

(μ˜ˆμ‹œμ˜ iu μΈμŠ€ν„΄μŠ€ μž…μž₯μ—μ„œλŠ”, singλ©”μ„œλ“œλ₯Ό μ‹€ν–‰ν–ˆμ„ λ•Œ constructor의 singλ©”μ„œλ“œκΉŒμ§€ κ°ˆν•„μš”μ—†μ΄ μžμ‹ μ˜ scopeλ‚΄ singλ©”μ„œλ“œλ₯Ό μ‹€ν–‰μ‹œν‚¨ 것이고, 이 λ©”μ„œλ“œμ—μ„œ ν•„μš”ν•œ song μ—­μ‹œ μƒμœ„μ—μ„œ 찾을 ν•„μš”μ—†μ΄ μžμ‹ μ˜ μœ„μΉ˜λ‚΄ μ •μ˜λœ songν”„λ‘œνΌν‹°λ₯Ό μ‚¬μš©ν•œ 것이닀.

반면 biberλŠ” μΈμŠ€ν„΄μŠ€ 객체 내뢀에 singλ©”μ„œλ“œκ°€ μ—†μœΌλ―€λ‘œ ν”„λ‘œν† νƒ€μž…μ²΄μΈμ„ λ”°λΌμ˜¬λΌκ°€ μƒμ„±μžν•¨μˆ˜μ˜ singλ©”μ„œλ“œλ₯Ό μ‹€ν–‰ν•œλ‹€. )


과거의 λ‚΄κ°€ λ³΄λ‚΄λŠ” 참고링크 -_-

profile
μ•„ν‹°ν΄λ¦¬μŠ€νŠΈ - bit.ly/3wjIlZJ

0개의 λŒ“κΈ€