JavaScript - this(1)

JavaScript - this

상황에 따라 λ‹¬λΌμ§€λŠ” this

  • μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ thisλŠ” 기본적으둜 μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ 생성될 λ•Œ ν•¨κ»˜ κ²°μ • => 즉, thisλŠ” ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  λ•Œ κ²°μ •λœλ‹€
  • ν•¨μˆ˜λ₯Ό μ–΄λ–€ λ°©μ‹μœΌλ‘œ ν˜ΈμΆœν•˜λŠλƒμ— 따라 값이 달라진닀.

μ „μ—­ κ³΅κ°„μ—μ„œμ˜ this

  • μ „μ—­ κ³΅κ°„μ—μ„œ thisλŠ” β€œμ „μ—­ 객체”λ₯Ό 가리킴
  • μ „μ—­ μ»¨ν…μŠ€νŠΈλ₯Ό μƒμ„±ν•˜λŠ” 주체 -> 전역객체이기 λ•Œλ¬Έ
  • μ „μ—­ κ°μ²΄λŠ” μžλ°”μŠ€ν¬λ¦½νŠΈ λŸ°νƒ€μž„ ν™˜κ²½μ— 따라 λ‹€λ₯Έ 이름과 정보
    • λΈŒλΌμš°μ € ν™˜κ²½ : window
    • Node.js ν™˜κ²½ : global

μ „μ—­λ³€μˆ˜μ™€ 전역객체

var a = 1;
console.log(a);
console.log(window.a);
console.log(this.a);

μ „μ—­κ³΅κ°„μ—μ„œ μ„ μ–Έν•œ λ³€μˆ˜ a에 1을 ν• λ‹Ήν–ˆμ„ 뿐인데 window.a와 this.aκ°€ λ™μΌν•˜κ²Œ 1이 좜λ ₯λœλ‹€. πŸ‘‰πŸ» κ·Έ μ΄μœ λŠ”, μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ λͺ¨λ“  λ³€μˆ˜λŠ” 싀은 νŠΉμ • 객체의 ν”„λ‘œνΌν‹°λ‘œμ„œ λ™μž‘ν•˜κΈ° λ•Œλ¬Έ

  • μ‚¬μš©μžκ°€ var μ—°μ‚°μžλ₯Ό μ΄μš©ν•΄ λ³€μˆ˜λ₯Ό μ„ μ–Έν•˜λ”λΌλ„ μ‹€μ œ μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 μ–΄λ–€ νŠΉμ • 객체의 ν”„λ‘œνΌν‹°λ‘œ 인식(νŠΉμ • κ°μ²΄λž€? μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ˜ LexicalEnvironment)
  • μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλŠ” λ³€μˆ˜λ₯Ό μˆ˜μ§‘ν•˜μ—¬ L.E의 ν”„λ‘œνΌν‹°λ‘œ μ €μž₯
  • μ „μ—­ μ»¨ν…μŠ€νŠΈμ˜ 경우, L.EλŠ” 전역객체 κ·ΈλŒ€λ‘œ μ°Έμ‘°( = GlobalEnvκ°€ μ „μ—­ 객체 μ°Έμ‘° / μ „μ—­ μ»¨ν…μŠ€νŠΈμ˜ L.Eκ°€ GlobalEnv μ°Έμ‘°)

πŸ”₯ β€œμ „μ—­λ³€μˆ˜λ₯Ό μ„ μ–Έν•˜λ©΄ μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 이λ₯Ό μ „μ—­κ°μ²΄μ˜ ν”„λ‘œνΌλ¦¬λ‘œ ν• λ‹Ήν•œλ‹€β€

μ „μ—­κ³΅κ°„μ—μ„œλŠ” var둜 λ³€μˆ˜λ₯Ό μ„ μ–Έν•˜λŠ” λŒ€μ‹  window의 ν”„λ‘œνΌν‹°μ— 직접 ν• λ‹Ήν•˜λ”λΌλ„ κ²°κ³Όμ μœΌλ‘œλŠ” var둜 μ„ μ–Έν•œ 것도 λ˜‘κ°™μ΄ λ™μž‘ν•  κ²ƒμ΄λΌλŠ” μ˜ˆμƒ κ°€λŠ₯

var a = 1;
window.b = 2;
console.log(a, window.a, this.a);
console.log(b, window.b, this.b);

window.a = 3;
b = 4;
console.log(a, window.a, this.a);
console.log(b, window.b, this.b);

μ „μ—­λ³€μˆ˜ μ„ μ–Έκ³Ό μ „μ—­κ°μ²΄μ˜ ν”„λ‘œνΌν‹° ν• λ‹Ή 사이에 μ „ν˜€ λ‹€λ₯Έ 경우 ➑️ μ‚­μ œ λͺ…λ Ή

  • μ „μ—­ κ°μ²΄λŠ” delete λͺ…령이 λΆˆκ°€λŠ₯ν•˜κ³ , μ „μ—­ 객체의 ν”„λ‘œνΌν‹°λŠ” delete λͺ…λ Ή λ™μž‘
    • μ΄λŠ” μ‚¬μš©μžκ°€ μ˜λ„μΉ˜ μ•Šκ²Œ μ‚­μ œν•˜λŠ” 것을 λ°©μ§€ν•˜λŠ” μ°¨μ›μ—μ„œ λ§ˆλ ¨ν•œ λ‚˜λ¦„μ˜ λ°©μ–΄ μ „λž΅ 해석

λ©”μ„œλ“œλ‘œμ„œ ν˜ΈμΆœν•  λ•Œ κ·Έ λ©”μ„œλ“œ λ‚΄λΆ€μ—μ„œμ˜ this

ν•¨μˆ˜ vs λ©”μ„œλ“œ

  • ν•¨μˆ˜
    • κ·Έ 자체둜 독립적인 κΈ°λŠ₯을 μˆ˜ν–‰
    • 점(.)μ΄λ‚˜ λŒ€κ΄„ν˜Έκ°™μ€ 것 ❌

  • λ©”μ„œλ“œ
    • μžμ‹ μ„ ν˜ΈμΆœν•œ λŒ€μƒ 객체에 κ΄€ν•œ λ™μž‘ μˆ˜ν–‰
    • 점(.)μ΄λ‚˜ λŒ€κ΄„ν˜Έκ°™μ€ 것 ⭕️

λ©”μ„œλ“œ λ‚΄λΆ€μ—μ„œμ˜ this

  • μ–΄λ–€ ν•¨μˆ˜λ₯Ό λ©”μ„œλ“œλ‘œμ„œ ν˜ΈμΆœν•˜λŠ” 경우, 호좜 μ£Όμ²΄λŠ” λ°”λ‘œ ν•¨μˆ˜λͺ…(ν”„λ‘œνΌν‹°λͺ…) μ•žμ˜ 객체
  • 점 ν‘œκΈ°λ²•μ˜ 경우, λ§ˆμ§€λ§‰ 점 μ•žμ— λͺ…μ‹œλœ 객체가 곧 this

ν•¨μˆ˜λ‘œμ„œ ν˜ΈμΆœν•  λ•Œ κ·Έ ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œμ˜ this

ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œμ˜ this

  • μ–΄λ–€ ν•¨μˆ˜λ₯Ό ν•¨μˆ˜λ‘œμ„œ ν˜ΈμΆœν•  κ²½μš°μ—λŠ” this 지정 ❌
  • ν•¨μˆ˜μ—μ„œμ˜ thisλŠ” μ „μ—­ 객체λ₯Ό 가리킨닀.

λ©”μ„œλ“œμ˜ λ‚΄λΆ€ν•¨μˆ˜μ—μ„œμ˜ this

μ •λ‹΅ ➑️ (1):obj1, (2):전역객체(window), (3):obj2

1 var obj1 = {
2  outer:function() {
3    console.log(this);   //(1)
4    var innerFunc = function () {
5      console.log(this);  //(2) (3)
6    }
7    innerFunc();
8
9    var obj2 = {
10      innerMethod : innerFunc
11    };
12    obj2.innerMethod();
13  }
14 };
15 obj1.outer();

2️⃣ λ²ˆμ€„

  • obj1.outerν•¨μˆ˜μ˜ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ 생성 및 ν˜Έμ΄μŠ€νŒ…, μŠ€μ½”ν”„ 체인 μ •λ³΄μˆ˜μ§‘, this 바인딩
  • ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  λ•Œ ν•¨μˆ˜λͺ…인 outer μ•žμ— 점(.)이 μžˆμ—ˆμœΌλ―€λ‘œ, λ©”μ„œλ“œλ‘œμ„œμ˜ 호좜 ➑️ λ§ˆμ§€λ§‰ 점 μ•žμ˜ 객체인 obj1 바인딩

4️⃣ λ²ˆμ€„

  • innerFunc ν•¨μˆ˜μ˜ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ 생성 및 ν˜Έμ΄μŠ€νŒ…, μŠ€μ½”ν”„ 체인 μˆ˜μ§‘, this 바인딩 λ“± μˆ˜ν–‰
  • ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  λ•Œ, 점(.) ❌
  • ν•¨μˆ˜λ‘œμ„œ ν˜ΈμΆœν•œ κ²ƒμ΄λ―€λ‘œ, thisκ°€ 지정 ❌ ➑️ μžλ™μœΌλ‘œ μŠ€μ½”ν”„ μ²΄μΈμƒμ˜ μ΅œμƒμœ„ 객체인 전역객체(window) 바인딩

9️⃣ λ²ˆμ€„

  • obj2.innerMethod ν•¨μˆ˜μ˜ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ 생성
  • ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  λ•Œ ν•¨μˆ˜λͺ…인 innerMethod μ•žμ— 점(.)이 μžˆμ—ˆμœΌλ―€λ‘œ λ©”μ„œλ“œλ‘œμ„œμ˜ 호좜 ➑️ λ§ˆμ§€λ§‰ 점 μ•žμ˜ 객체인 obj2 바인딩

πŸ”₯ 였직 ν•΄λ‹Ή ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λŠ” ꡬ문 μ•žμ— 점 λ˜λŠ” λŒ€κ΄„ν˜Έ ν‘œκΈ°κ°€ μžˆλŠ”μ§€ μ—†λŠ”μ§€κ°€ 관건

λ©”μ„œλ“œμ˜ λ‚΄λΆ€ ν•¨μˆ˜μ—μ„œμ˜ thisλ₯Ό μš°νšŒν•˜λŠ” 방법

✨ λ³€μˆ˜λ₯Ό ν™œμš©ν•˜λŠ” 것

var obj = {
  outer: function () {
    console.log(this); // (1) {outer: f}
    var innerFunc1 = function () {
      console.log(this); // (2) window{ ... }
    };
    innerFunc1();
    // μ—¬κΈ°μ„œ thisλ₯Ό λ³€μˆ˜μ— ν• λ‹Ή
    var self = this;
    var innerFunc2 = function () {
      console.log(self); // (3) {outer: f}
    };
    innerFunc2();
  },
};
obj.outer();

thisλ₯Ό 바인딩 ν•˜μ§€ μ•ŠλŠ” ν•¨μˆ˜

  • ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ thisκ°€ 전역객체λ₯Ό λ°”λΌλ³΄λŠλ‚˜ 문제λ₯Ό λ³΄μ™„ν•˜κ³ μž, thisλ₯Ό 바인딩 ν•˜μ§€μ•ŠλŠ” ν™”μ‚΄ν‘œν•¨μˆ˜(arrow function) λ„μž… (ES6)
  • ν™”μ‚΄ν‘œν•¨μˆ˜(arrow function)λŠ” μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλ₯Ό 생성할 λ•Œ this 바인딩 κ³Όμ • μžμ²΄κ°€ λΉ μ§€κ²Œ λ˜μ–΄, μƒμœ„ μŠ€μ½”ν”„μ˜ thisλ₯Ό κ·ΈλŒ€λ‘œ ν™œμš© κ°€λŠ₯
var obj = {
  outer: function () {
    console.log(this);
    var innerFunc = () => {
      console.log(this);
    };
    innerFunc();
  },
};
obj.outer();

콜백 ν•¨μˆ˜ 호좜 μ‹œ κ·Έ ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œμ˜ this

  • ν•¨μˆ˜ A의 μ œμ–΄κΆŒμ„ λ‹€λ₯Έ ν•¨μˆ˜(λ˜λŠ” λ©”μ„œλ“œ) Bμ—κ²Œ λ„˜κ²¨μ£ΌλŠ” 경우 ν•¨μˆ˜ Aλ₯Ό μ½œλ°±ν•¨μˆ˜
  • ν•¨μˆ˜ AλŠ” ν•¨μˆ˜ B의 λ‚΄λΆ€ λ‘œμ§μ— 따라 μ‹€ν–‰
  • this μ—­μ‹œ ν•¨μˆ˜ B λ‚΄λΆ€ λ‘œμ§μ—μ„œ μ •ν•œ κ·œμΉ™μ— 따라 κ°’ κ²°μ •
  • μ œμ–΄κΆŒμ„ 받은 ν•¨μˆ˜μ—μ„œ 콜백 ν•¨μˆ˜μ— λ³„λ„λ‘œ thisκ°€ 될 λŒ€μƒμ„ μ§€μ •ν•œ 경우 κ·Έ λŒ€μƒμ„ μ°Έμ‘°

μƒμ„±μž ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œμ˜ this

  • μƒμ„±μž ν•¨μˆ˜ : μ–΄λ–€ κ³΅ν†΅λœ μ„±μ§ˆμ„ μ§€λ‹ˆλŠ 객체듀을 μƒμ„±ν•˜λŠ”λ° μ‚¬μš©ν•˜λŠ” ν•¨μˆ˜
  • μƒμ„±μž : ν”„λ‘œκ·Έλž˜λ°μ μœΌλ‘œ ꡬ체적인 μΈμŠ€ν„΄μŠ€λ₯Ό λ§Œλ“€κΈ° μœ„ν•œ μΌμ’…μ˜ ν‹€
  • μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” ν•¨μˆ˜μ— μƒμ„±μžλ‘œμ„œμ˜ 역할을 ν•¨κ»˜ λΆ€μ—¬
    • new λͺ…령어와 ν•¨κ»˜ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λ©΄ ν•΄λ‹Ή ν•¨μˆ˜κ°€ μƒμ„±μžλ‘œμ„œ λ™μž‘
  • μ–΄λ–€ ν•¨μˆ˜κ°€ μƒμ„±μž ν•¨μˆ˜λ‘œμ„œ 호좜된 경우 λ‚΄λΆ€μ—μ„œμ˜ thisλŠ” 곧 μƒˆλ‘œ λ§Œλ“€ ꡭ체적인 μΈμŠ€ν„΄μŠ€ μžμ‹ 
var Cat = function (name, age) {
  this.bark = "μ•Όμ˜Ή";
  this.name = name;
  this.age = age;
};
var choco = new Cat("μ΄ˆμ½”", 7);
var nabi = new Cat("λ‚˜λΉ„", 5);
console.log(choco, nabi);

μ°Έκ³  : μ½”μ–΄ μžλ°”μŠ€ν¬λ¦½νŠΈ(Core JavaScript), μ •μž¬λ‚¨