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

🌈 Chapter 3: this

πŸ“š 상황에 따라 λ‹¬λΌμ§€λŠ” this​

  • μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ thisλŠ” 기본적으둜 μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ 생성될 λ•Œ ν•¨κ»˜ κ²°μ •λœλ‹€.
  • μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλŠ” ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  λ•Œ μƒμ„±λ˜λ―€λ‘œ, λ°”κΏ” λ§ν•˜λ©΄ thisλŠ” ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  λ•Œ κ²°μ •λœλ‹€κ³  ν•  수 μžˆλ‹€.

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

  • μ „μ—­ κ³΅κ°„μ—μ„œ thisλŠ” μ „μ—­ 객체λ₯Ό 가리킨닀. μ „μ—­ κ°μ²΄λŠ” λŸ°νƒ€μž„ ν™˜κ²½μ— 따라 λΈŒλΌμš°μ € ν™˜κ²½μ—μ„œ μ „μ—­κ°μ²΄λŠ” window이고 Node.js ν™˜κ²½μ—μ„œλŠ” global이닀.
// λΈŒλΌμš°μ €
this === window

// Node.js
this === global
  • μ „μ—­λ³€μˆ˜λ₯Ό μ„ μ–Έν•˜λ©΄ μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 이λ₯Ό μ „μ—­κ°μ²΄μ˜ ν”„λ‘œνΌν‹°λ‘œλ„ ν• λ‹Ήν•œλ‹€. λ³€μˆ˜μ΄λ©΄μ„œ 객체의 ν”„λ‘œνΌν‹°μ΄κΈ°λ„ ν•˜λ‹€.
var a = 1;
console.log(a); // 1
console.log(window.a); // 1
console.log(this.a); // 1
  • μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ λͺ¨λ“  λ³€μˆ˜λŠ” νŠΉμ • 객체의 ν”„λ‘œνΌν‹°λ‘œμ„œ λ™μž‘ν•œλ‹€. var μ—°μ‚°μžλ₯Ό μ΄μš©ν•΄ λ³€μˆ˜λ₯Ό μ„ μ–Έν•˜λ”λΌλ„ μ‹€μ œ μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 μ–΄λ–€ νŠΉμ • 객체의 ν”„λ‘œνΌν‹°λ‘œ μΈμ‹ν•œλ‹€. μ—¬κΈ°μ„œ νŠΉμ • κ°μ²΄λž€ λ°”λ‘œ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ˜ LexicalEnvironment이닀. μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλŠ” λ³€μˆ˜λ₯Ό μˆ˜μ§‘ν•΄μ„œ LexicalEnvironment의 ν”„λ‘œνΌν‹°λ‘œ μ €μž₯ν•œλ‹€. 이후 μ–΄λ–€ λ³€μˆ˜λ₯Ό ν˜ΈμΆœν•˜λ©΄ LexicalEnvironmentλ₯Ό μ‘°νšŒν•΄μ„œ μΌμΉ˜ν•˜λŠ” ν”„λ‘œνΌν‹°κ°€ μžˆμ„ 경우 κ·Έ 값을 λ°˜ν™˜ν•œλ‹€. μ „μ—­ μ»¨ν…μŠ€νŠΈμ˜ 경우 LexicalEnvironmentλŠ” 전역객체λ₯Ό κ·ΈλŒ€λ‘œ μ°Έμ‘°ν•œλ‹€. (μ •ν™•νžˆλŠ” GlobalEnvλ₯Ό μ°Έμ‘°)
  • μ „μ—­λ³€μˆ˜λ₯Ό μ„ μ–Έν•˜λ©΄ μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 이λ₯Ό μ „μ—­κ°μ²΄μ˜ ν”„λ‘œνΌν‹°λ‘œ ν• λ‹Ήν•œλ‹€.
  • μ—¬κΈ°μ„œ a만 ν˜ΈμΆœν•˜μ—¬λ„ 1이 λ‚˜μ˜€λŠ” μ΄μœ λŠ” λ³€μˆ˜ a에 μ ‘κ·Όν•˜κ³ μž ν•˜λ©΄ μŠ€μ½”ν”„ μ²΄μΈμ—μ„œ aλ₯Ό κ²€μƒ‰ν•˜λ‹€κ°€ κ°€μž₯ λ§ˆμ§€λ§‰μ— λ„λ‹¬ν•˜λŠ” μ „μ—­ μŠ€μ½”ν”„μ˜ LexicalEnvironment 즉, μ „μ—­ κ°μ²΄μ—μ„œ ν•΄λ‹Ή ν”„λ‘œνΌν‹° aλ₯Ό λ°œκ²¬ν•΄μ„œ κ·Έ 값을 λ°˜ν™˜ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€.
// var둜 λ³€μˆ˜λ₯Ό μ„ μ–Έν•˜λŠ” λŒ€μ‹  window의 ν”„λ‘œνΌν‹°μ— 직접 ν• λ‹Ήν•˜λ”λΌλ„ λŒ€λΆ€λΆ„μ˜ κ²½μš°λŠ” λ˜‘κ°™μ΄ λ™μž‘ν•œλ‹€.
var a = 1;
window.b = 2;

console.log(a, window.a, this.a); // 1 1 1
console.log(b, window.b, this.b); // 2 2 2
  • 그런데 μ „μ—­λ³€μˆ˜ μ„ μ–Έκ³Ό μ „μ—­κ°μ²΄μ˜ ν”„λ‘œνΌν‹° ν• λ‹Ή 사이에 μ „ν˜€ λ‹€λ₯Έ κ²½μš°λ„ μžˆλŠ”λ° λ°”λ‘œ μ‚­μ œ λͺ…령에 λŒ€ν•΄ κ·Έλ ‡λ‹€.
var a = 1;
delete window.a; // false
console.log(a, window.a, this.a); // 1 1 1

window.c = 3;
delete window.c; // true
console.log(c, window.c, this.c); // Uncaught ReferenceError: c is not defined
  • μ „μ—­κ°μ²΄μ˜ ν”„λ‘œνΌν‹°λ‘œ ν• λ‹Ήν•œ κ²½μš°μ—λŠ” μ‚­μ œκ°€ λ˜λŠ” 반면 μ „μ—­λ³€μˆ˜λ‘œ μ„ μ–Έν•  κ²½μš°μ—λŠ” μ‚­μ œκ°€ λ˜μ§€ μ•ŠλŠ”λ‹€. μ΄λŠ” μ‚¬μš©μžκ°€ μ˜λ„μΉ˜ μ•Šκ²Œ μ‚­μ œν•˜λŠ” 것을 λ°©μ§€ν•˜λŠ” μ°¨μ›μ—μ„œ λ§ˆλ ¨ν•œ λ°©μ–΄ μ „λž΅μ΄λ‹€.

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

🐢 ν•¨μˆ˜ vs. λ©”μ„œλ“œβ€‹

  • ν•¨μˆ˜μ™€ λ©”μ„œλ“œλ₯Ό κ΅¬λΆ„ν•˜λŠ” μœ μΌν•œ μ°¨μ΄λŠ” 독립성에 μžˆλ‹€. ν•¨μˆ˜λŠ” κ·Έ 자체둜 독립적인 κΈ°λŠ₯을 μˆ˜ν–‰ν•˜λŠ” 반면, λ©”μ„œλ“œλŠ” μžμ‹ μ„ ν˜ΈμΆœν•œ λŒ€μƒ 객체에 κ΄€ν•œ λ™μž‘μ„ μˆ˜ν–‰ν•œλ‹€.
// ν•¨μˆ˜λ‘œμ„œ 호좜, λ©”μ„œλ“œλ‘œμ„œ 호좜
var func = function (x) {
console.log(this, x);
};

func(1); // Window {...} 1

var obj = {
method: func
};

obj.method(2); // { method: f } 2
  • μ›λž˜ 읡λͺ…ν•¨μˆ˜λŠ” κ·ΈλŒ€λ‘œμΈλ° 이λ₯Ό λ³€μˆ˜μ— λ‹΄μ•„ ν˜ΈμΆœν•œ κ²½μš°μ™€ obj 객체의 ν”„λ‘œνΌν‹°μ— ν• λ‹Ήν•΄μ„œ ν˜ΈμΆœν•œ κ²½μš°μ— thisκ°€ 달라진닀.

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

  • thisμ—λŠ” ν˜ΈμΆœν•œ 주체에 λŒ€ν•œ 정보가 λ‹΄κΈ΄λ‹€. μ–΄λ–€ ν•¨μˆ˜λ₯Ό λ©”μ„œλ“œλ‘œμ„œ ν˜ΈμΆœν•˜λŠ” 경우 호좜 μ£Όμ²΄λŠ” λ°”λ‘œ ν•¨μˆ˜(ν”„λ‘œνΌν‹°λͺ…) μ•žμ˜ 객체이닀. 점 ν‘œκΈ°λ²•μ˜ 경우 λ§ˆμ§€λ§‰ 점 μ•žμ— λͺ…μ‹œλœ 객체가 곧 thisκ°€ λœλ‹€.
var obj = {
methodA: function() { console.log(this); },
inner: {
methodB: function() { console.log(this); },
},
};

obj.methodA(); // { methodA: f, inner: {...} } ( === obj)
obj.inner.methodB(); // { methodB: f } ( === obj.inner)

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

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

  • μ–΄λ–€ ν•¨μˆ˜λ₯Ό ν•¨μˆ˜λ‘œμ„œ ν˜ΈμΆœν•  κ²½μš°μ—λŠ” thisκ°€ μ§€μ •λ˜μ§€ μ•ŠλŠ”λ‹€. ν•¨μˆ˜λ‘œμ„œ ν˜ΈμΆœν•˜λŠ” 것은 호좜 주체λ₯Ό λͺ…μ‹œν•˜μ§€ μ•Šκ³  κ°œλ°œμžκ°€ μ½”λ“œμ— 직접 κ΄€μ—¬ν•΄μ„œ μ‹€ν–‰ν•œ 것이기 λ•Œλ¬Έμ— 호좜 주체의 정보λ₯Ό μ•Œ 수 μ—†λ‹€.
  • κ·Έλ ‡κΈ° λ•Œλ¬Έμ— thisκ°€ μ§€μ •λ˜μ§€ μ•Šμ•˜κΈ°μ— thisλŠ” μ „μ—­ 객체λ₯Ό κ°€ν‚€λ¦°λ‹€.
  • 이것은 μ„€κ³„μƒμ˜ 였λ₯˜μ΄λ‹€.

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

var obj1 = {
outer: function () {
console.log(this); // (1)

var innerFunc = function () {
console.log(this); // (2) (3)
}

innerFunc();

var obj2 = {
innerMethod: innerFunc
};

obj2.innerMethod();
}
};

obj1.outer();
  • (1)은 obj1, (2)λŠ” 전역객체(Window) (3)은 obj2이닀.
    1. obj1.outerλ₯Ό ν˜ΈμΆœν•œλ‹€.
    2. obj1.outer ν•¨μˆ˜μ˜ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ μƒμ„±λ˜λ©΄μ„œ ν˜Έμ΄μŠ€νŒ…ν•˜κ³ , μŠ€μ½”ν”„ 체인 정보λ₯Ό μˆ˜μ§‘ν•˜κ³ , thisλ₯Ό λ°”μΈλ”©ν•œλ‹€. 이 ν•¨μˆ˜λŠ” ν˜ΈμΆœν•  λ•Œ ν•¨μˆ˜λͺ…인 outer μ•žμ— 점이 μžˆμ—ˆμœΌλ―€λ‘œ λ©”μ„œλ“œλ‘œμ„œ ν˜ΈμΆœν•œ 것이닀. λ”°λΌμ„œ thisμ—λŠ” λ§ˆμ§€λ§‰ 점 μ•žμ˜ 객체인 obj1이 λ°”μΈλ”©λœλ‹€.
    3. obj1의 객체 정보가 좜λ ₯λœλ‹€.
    4. ν˜Έμ΄μŠ€νŒ…λœ λ³€μˆ˜ innerFuncλŠ” outer μŠ€μ½”ν”„ λ‚΄μ—μ„œλ§Œ μ ‘κ·Όν•  수 μžˆλŠ” μ§€μ—­λ³€μˆ˜μ΄λ‹€. 이 μ§€μ—­λ³€μˆ˜μ— 읡λͺ… ν•¨μˆ˜λ₯Ό ν• λ‹Ήν•œλ‹€.
    5. innerFuncλ₯Ό ν˜ΈμΆœν•œλ‹€.
    6. innerFunc ν•¨μˆ˜μ˜ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ μƒμ„±λ˜λ©΄μ„œ ν˜Έμ΄μŠ€νŒ…ν•˜κ³ , μŠ€μ½”ν”„ 체인 정보λ₯Ό μˆ˜μ§‘ν•˜κ³ , thisλ₯Ό λ°”μΈλ”©ν•œλ‹€. 이 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  λ•Œ ν•¨μˆ˜λͺ… μ•žμ—λŠ” 점이 μ—†λ‹€. 즉 ν•¨μˆ˜λ‘œμ„œ ν˜ΈμΆœν•œ κ²ƒμ΄λ―€λ‘œ thisκ°€ μ§€μ •λ˜μ§€ μ•Šμ•˜κ³ , λ”°λΌμ„œ μžλ™μœΌλ‘œ μŠ€μ½”ν”„ μ²΄μΈμƒμ˜ μ΅œμƒμœ„ 객체인 전역객체(Window)κ°€ λ°”μΈλ”©λœλ‹€.
    7. Window 객체 정보가 좜λ ₯λœλ‹€.
    8. ν˜Έμ΄μŠ€νŒ…λœ λ³€μˆ˜ obj2 μ—­μ‹œ outer μŠ€μ½”ν”„ λ‚΄μ—μ„œλ§Œ μ ‘κ·Όν•  수 μžˆλŠ” μ§€μ—­λ³€μˆ˜μ΄λ‹€. μ—¬κΈ°μ„œ λ‹€μ‹œ 객체λ₯Ό ν• λ‹Ήν•˜λŠ”λ°, κ·Έ κ°μ²΄μ—λŠ” innerMethodλΌλŠ” ν”„λ‘œνΌν‹°κ°€ 있으며 μ—¬κΈ°μ—λŠ” μ•žμ„œ μ •μ˜λœ λ³€μˆ˜ innerFunc와 μ—°κ²°λœ 읡λͺ… ν•¨μˆ˜κ°€ μ—°κ²°λœλ‹€.
    9. obj2.innerMethodλ₯Ό ν˜ΈμΆœν•œλ‹€.
    10. obj2.innerMethod ν•¨μˆ˜μ˜ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ μƒμ„±λ˜κ³  이 ν•¨μˆ˜λŠ” ν˜ΈμΆœν•  λ•Œ ν•¨μˆ˜λͺ…인 innerMethod μ•žμ— 점이 μžˆμ—ˆμœΌλ―€λ‘œ λ©”μ„œλ“œλ‘œμ„œ ν˜ΈμΆœν•œ 것이닀. λ”°λΌμ„œ thisμ—λŠ” λ§ˆμ§€λ§‰ 점 μ•žμ˜ 객체인 obj2κ°€ λ°”μΈλ”©λœλ‹€.
    11. obj2 객체 정보가 좜λ ₯λœλ‹€.
  • μœ„μ˜ μ˜ˆμ œμ™€ 같이 this 바인딩에 κ΄€ν•΄μ„œλŠ” ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•˜λŠ” λ‹Ήμ‹œ μ£Όλ³€ ν™˜κ²½μ€ μ€‘μš”ν•˜μ§€ μ•Šκ³ , 였직 ν•΄λ‹Ή ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λŠ” ꡬ문 μ•žμ— 점 λ˜λŠ” λŒ€κ΄„ν˜Έ ν‘œκΈ°κ°€ μžˆλŠ”μ§€ μ—†λŠ”μ§€κ°€ 관건이닀.

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

  • 호좜 주체가 없을 λ•ŒλŠ” μžλ™μœΌλ‘œ 전역객체λ₯Ό λ°”μΈλ”©ν•˜μ§€ μ•Šκ³  호좜 λ‹Ήμ‹œ μ£Όλ³€ ν™˜κ²½μ˜ thisλ₯Ό κ·ΈλŒ€λ‘œ 상속받아 μ‚¬μš©ν•  수 있으면 쒋을것이닀. ν•˜μ§€λ§Œ ES5κΉŒμ§€λŠ” 자체적으둜 λ‚΄λΆ€ν•¨μˆ˜μ— thisλ₯Ό 상속할 방법이 μ—†μ§€λ§Œ μš°νšŒν•  방법이 μžˆλ‹€. λŒ€μ€‘μ μΈ λ°©λ²„μœΌλ‘œ λ³€μˆ˜λ₯Ό ν™œμš©ν•œ 방법이닀.
var obj1 = {
outer: function () {
console.log(this); // (1) { outer: f }

var innerFunc1 = function () {
console.log(this); // (2) Window {...}
}

innerFunc1();

var self = this;
var innerFunc2 = function () {
console.log(self); // (3) { outer: f }
};

innerFunc2();
}
};

obj1.outer();
  • selfλŠ” κ·Έμ € μƒμœ„ μŠ€μ½”ν”„μ˜ thisλ₯Ό μ €μž₯ν•΄μ„œ λ‚΄λΆ€ν•¨μˆ˜μ—μ„œ ν™œμš”ν•˜λ €λŠ” μˆ˜λ‹¨μ΄λ‹€.

🐢 thisλ₯Ό λ°”μΈλ”©ν•˜μ§€ μ•ŠλŠ” ν•¨μˆ˜β€‹

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

var innerFunc = () => {
console.log(this); // (2) { outer: f }
};

innerFunc();
},
};

obj.outer();
  • κ·Έ 밖에도 call, apply λ“±μ˜ λ©”μ„œλ“œλ₯Ό ν™œμš©ν•΄ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  λ•Œ λͺ…μ‹œμ μœΌλ‘œ thisλ₯Ό μ§€μ •ν•˜λŠ” 방법이 μžˆλ‹€.

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

  • ν•¨μˆ˜ A의 μ œμ–΄κΆŒμ„ λ‹€λ₯Έ ν•¨μˆ˜ Bμ—κ²Œ λ„˜κ²¨μ£ΌλŠ” 경우 ν•¨μˆ˜ Aλ₯Ό 콜백 ν•¨μˆ˜λΌ ν•œλ‹€. μ΄λ•Œ ν•¨μˆ˜ AλŠ” ν•¨μˆ˜ B의 λ‚΄λΆ€ λ‘œμ§μ— 따라 μ‹€ν–‰λ˜λ©°, this μ—­μ‹œ ν•¨μˆ˜ B λ‚΄λΆ€ λ‘œμ§μ—μ„œ μ •ν•œ κ·œμΉ™μ— 따라 값이 κ²°μ •λœλ‹€.
  • 콜백 ν•¨μˆ˜λ„ ν•¨μˆ˜μ΄κΈ° λ•Œλ¬Έμ— 기본적으둜 thisκ°€ 전역객체λ₯Ό μ°Έμ‘°ν•˜μ§€λ§Œ, μ œμ–΄κΆŒμ„ 받은 ν•¨μˆ˜μ—μ„œ 콜백 ν•¨μˆ˜μ— λ³„λ„λ‘œ thisκ°€ 될 λŒ€μƒμ„ μ§€μ •ν•œ κ²½μš°μ—λŠ” κ·Έ λŒ€μƒμ„ μ°Έμ‘°ν•˜κ²Œ λœλ‹€.
setTimeout(function () { console.log(this); }, 300); // (1)

[1, 2, 3, 4, 5].forEach(function (x) { // (2)
console.log(this, x);
});

document.body.innerHTML += '<button id="a">클릭</button>';
document.body.querySelector('#a')
.addEventListener('click', function (e) { // (3)
console.log(this, e);
});
  • 1λ²ˆμ€ 300ms만큼 μ‹œκ°„ 지연을 ν•œ λ’€ 콜백 ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•˜λΌλŠ” λͺ…령이닀. 0.3초 λ’€ 전역객체가 좜λ ₯λœλ‹€.
  • 2λ²ˆμ€ 전역객체와 λ°°μ—΄μ˜ 각 μš”μ†Œκ°€ 총 5회 좜λ ₯λœλ‹€.
  • 3λ²ˆμ€ 버큰을 ν΄λ¦­ν•˜λ©΄ μ•žμ„œ μ§€μ •ν•œ μ—˜λ¦¬λ¨ΌνŠΈμ™€ 클릭 μ΄λ²€νŠΈμ— κ΄€ν•œ 정보가 λ‹΄κΈ΄ 객체가 좜λ ₯λœλ‹€.
  • 1번과 2λ²ˆμ€ κ·Έ λ°°λˆ„μ—μ„œ 콜백 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  λ•Œ λŒ€μƒμ΄ 될 thisλ₯Ό μ§€μ •ν•˜μ§€ μ•ŠλŠ”λ‹€. λ”°λΌμ„œ 콜백 ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œμ˜ thisλŠ” 전역객체λ₯Ό μ°Έμ‘°ν•œλ‹€.
  • 3λ²ˆμ€ 콜백 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  λ•Œ μžμ‹ μ˜ thisλ₯Ό μƒμ†ν•˜λ„λ‘ μ •μ˜λΌ μžˆλ‹€. κ·ΈλŸ¬λ‹ˆκΉŒ λ©”μ„œλ“œλͺ…μ˜ 점 μ•žλΆ€λΆ„μ΄ 곧 thisκ°€ λ˜λŠ” 것이닀.
  • κ·Έλ ‡κΈ° λ•Œλ¬Έμ— 콜백 ν•¨μˆ˜μ˜ μ œμ–΄κΆŒμ„ κ°€μ§€λŠ” ν•¨μˆ˜(λ©”μ„œλ“œ)κ°€ 콜백 ν•¨μˆ˜μ—μ„œμ˜ thisλ₯Ό λ¬΄μ—‡μœΌλ‘œ 할지λ₯Ό κ²°μ •ν•˜λ©°, νŠΉλ³„νžˆ μ •μ˜ν•˜μ§€ μ•Šμ€ κ²½μš°μ—λŠ” 기본적으둜 ν•¨μˆ˜μ™€ λ§ˆμ°¬κ°€μ§€λ‘œ 전역객체λ₯Ό 바라본닀.

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

  • μƒμ„±μž ν•¨μˆ˜λŠ” μ–΄λ–€ κ³΅ν†΅λœ μ„±μ§ˆμ„ μ§€λ‹ˆλŠ” 객체듀을 μƒμ„±ν•˜λŠ” 데 μ‚¬μš©ν•˜λŠ” ν•¨μˆ˜μ΄λ‹€.
  • μƒμ„±μžλŠ” ꡬ체적인 μΈμŠ€ν„΄μŠ€λ₯Ό λ§Œλ“€κΈ° μœ„ν•œ μΌμ’…μ˜ 틀이닀.
  • μ–΄λ–€ ν•¨μˆ˜κ°€ μƒμ„±μž ν•¨μˆ˜λ‘œμ„œ 호좜된 경우 λ‚΄λΆ€μ—μ„œμ˜ thisλŠ” 곧 μƒˆλ‘œ λ§Œλ“€ ꡬ체적인 μΈμŠ€ν„΄μŠ€ μžμ‹ μ΄ λœλ‹€.
  • μƒμ„±μž ν•¨μˆ˜λ₯Ό 호좜(new λͺ…령어와 ν•¨κ»˜ ν•¨μˆ˜λ₯Ό 호좜)ν•˜λ©΄ μš°μ„  μƒμ„±μžμ˜ prototype ν”„λ‘œνΌν‹°λ₯Ό μ°Έμ‘°ν•˜λŠ” __proto__λΌλŠ” ν”„λ‘œνΌν‹°κ°€ μžˆλŠ” 객체(μΈμŠ€ν„΄μŠ€)λ₯Ό λ§Œλ“€κ³ , 미리 μ€€λΉ„λœ 곡톡 속성 및 κ°œμ„±μ„ ν•΄λ‹Ή 객체(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);
// CatΒ {bark: "μ•Όμ˜Ή", name: "μ΄ˆμ½”", age: 7}
// CatΒ {bark: "μ•Όμ˜Ή", name: "λ‚˜λΉ„", age: 5}

πŸ“š λͺ…μ‹œμ μœΌλ‘œ thisλ₯Ό λ°”μΈλ”©ν•˜λŠ” 방법​

🎈 call λ©”μ„œλ“œβ€‹

Function.prototype.call(thisArg[, arg1[, arg2[, ...]]])
  • call λ©”μ„œλ“œλŠ” λ©”μ„œλ“œμ˜ 호좜 주체인 ν•¨μˆ˜λ₯Ό μ¦‰μ‹œ μ‹€ν–‰ν•˜λ„λ‘ ν•˜λŠ” λͺ…령이닀.
  • μ΄λ•Œ call λ©”μ„œλ“œμ˜ 첫 번째 인자λ₯Ό this둜 λ°”μΈλ”©ν•˜κ³ , μ΄ν›„μ˜ μΈμžλ“€μ„ ν˜ΈμΆœν•  ν•¨μˆ˜μ˜ λ§€κ°œλ³€μˆ˜λ‘œ ν•œλ‹€. ν•¨μˆ˜λ₯Ό κ·Έλƒ₯ μ‹€ν–‰ν•˜λ©΄ thisλŠ” 전역객체λ₯Ό μ°Έμ‘°ν•˜μ§€λ§Œ call λ©”μ„œλ“œλ₯Ό μ΄μš©ν•˜λ©΄ μž„μ˜μ˜ 객체λ₯Ό this둜 지정할 수 μžˆλ‹€.
var func = function (a, b, c) {
console.log(this, a, b, c);
};

func(1, 2, 3); // Window{ ... } 1 2 3
func.call({ x: 1 }, 4, 5, 6); // { x: 1 } 4 5 6
  • λ©”μ„œλ“œμ— λŒ€ν•΄μ„œλ„ λ§ˆμ°¬κ°€μ§€λ‘œ 객체의 λ©”μ„œλ“œλ₯Ό κ·Έλƒ₯ ν˜ΈμΆœν•˜λ©΄ thisλŠ” 객체λ₯Ό μ°Έμ‘°ν•˜μ§€λ§Œ call λ©”μ„œλ“œλ₯Ό μ΄μš©ν•˜λ©΄ μž„μ˜μ˜ 객체λ₯Ό this둜 지정할 수 μžˆλ‹€.
var obj = {
a: 1,
method: function(x, y) {
console.log(this.a, x, y);
}
};

obj.method(2, 3); // 1 2 3
obj.method.call({ a: 4 }, 5, 6); // 4 5 6

🎈 apply λ©”μ„œλ“œβ€‹

Function.prototype.apply(thisArg[, argsArray])
  • apply λ©”μ„œλ“œλŠ” call λ©”μ„œλ“œμ™€ κΈ°λŠ₯적으둜 μ™„μ „νžˆ λ™μΌν•˜λ‹€.
  • call λ©”μ„œλ“œλŠ” 첫 번째 인자λ₯Ό μ œμ™Έν•œ λ‚˜λ¨Έμ§€ λͺ¨λ“  μΈμžλ“€μ„ ν˜ΈμΆœν•  ν•¨μˆ˜μ˜ λ§€κ°œλ³€μˆ˜λ‘œ μ§€μ •ν•˜λŠ” 반면, apply λ©”μ„œλ“œλŠ” 두 번째 인자λ₯Ό λ°°μ—΄λ‘œ λ°›μ•„ κ·Έ λ°°μ—΄μ˜ μš”μ†Œλ“€μ„ ν˜ΈμΆœν•  ν•¨μˆ˜μ˜ λ§€κ°œλ³€μˆ˜λ‘œ μ§€μ •ν•œλ‹€λŠ” μ μ—μ„œλ§Œ 차이가 μžˆλ‹€.
var func = function(a, b, c) {
console.log(this, a, b, c);
};

func.apply({ x: 1 }, [4, 5, 6]); // { x: 1 } 4 5 6

var obj = {
a: 1,
method: function(x, y) {
console.log(this.a, x, y);
},
};

obj.method.apply({ a: 4 }, [5, 6]); // 4 5 6

🎈 call / apply λ©”μ„œλ“œμ˜ ν™œμš©β€‹

🐢 μœ μ‚¬λ°°μ—΄κ°μ²΄(array-like object)에 λ°°μ—΄ λ©”μ„œλ“œλ₯Ό μ μš©β€‹

var obj = {
0: 'a',
1: 'b',
2: 'c',
length: 3
};

Array.prototype.push.call(obj, 'd');
console.log(obj); // { 0: "a", 1: "b", 2: "c", 3: "d", length: 4 }

var arr = Array.prototype.slice.call(obj);
console.log(arr); // [ 'a', 'b', 'c', 'd' ]
  • κ°μ²΄μ—λŠ” λ°°μ—΄ λ©”μ„œλ“œλ₯Ό 직접 μ μš©ν•  수 μ—†μ§€λ§Œ, ν‚€κ°€ 0 λ˜λŠ” μ–‘μ˜ μ •μˆ˜μΈ ν”„λ‘œνΌν‹°κ°€ μ‘΄μž¬ν•˜κ³  length ν”„λ‘œνΌν‹° 값이 0 λ˜λŠ” μ–‘μ˜ μ •μˆ˜μΈ 객체, 즉 λ°°μ—΄μ˜ ꡬ쑰와 μœ μ‚¬ν•œ 객체의 경우(μœ μ‚¬λ°°μ—΄κ°μ²΄) call λ˜λŠ” apply λ©”μ„œλ“œλ₯Ό μ΄μš©ν•΄ λ°°μ—΄ λ©”μ„œλ“œλ₯Ό μ°¨μš©ν•  수 μžˆλ‹€.
  • ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ μ ‘κ·Όν•  수 μžˆλŠ” arguments 객체도 μœ μ‚¬λ°°μ—΄κ°μ²΄μ΄λ―€λ‘œ λ°°μ—΄λ‘œ μ „ν™˜ν•΄μ„œ ν™œμš©ν•  수 μžˆλ‹€. querySelectorAll, getElementsByClassName λ“±μ˜ Node μ„ νƒμžλ‘œ 선택할 결과인 NodeList도 λ§ˆμ°¬κ°€μ§€μ΄λ‹€.
function a() {
var argv = Array.prototype.slice.call(arguments);

argv.forEach(function (arg) {
console.log(arg);
});
}

a(1, 2, 3);
// 1
// 2
// 3

document.body.innerHTML = '<div>a</div><div>b</div><div>c</div>';
var nodeList = document.querySelectorAll('div');
var nodeArr = Array.prototype.slice.call(nodeList);

nodeArr.forEach(function (node) {
console.log(node);
});
// <div>a</div>
// <div>b</div>
// <div>c</div>
  • κ·Έ 밖에도 μœ μ‚¬λ°°μ—΄κ°μ²΄μ—λŠ” call/apply λ©”μ„œλ“œλ₯Ό μ΄μš©ν•΄ λͺ¨λ“  λ°°μ—΄ λ©”μ„œλ“œλ₯Ό μ μš©ν•  수 μžˆλ‹€.
  • λ°°μ—΄μ²˜λŸΌ μΈλ±μŠ€μ™€ length ν”„λ‘œνΌν‹°λ₯Ό μ§€λ‹ˆλŠ” λ¬Έμžμ—΄μ— λŒ€ν•΄μ„œλ„ λ§ˆμ°¬κ°€μ§€μ΄λ‹€. 단, λ¬Έμžμ—΄μ˜ 경우 length ν”„λ‘œνΌν‹°κ°€ 읽기 μ „μš©μ΄κΈ° λ•Œλ¬Έμ— 원본 λ¬Έμžμ—΄μ— 변경을 κ°€ν•˜λŠ” λ©”μ„œλ“œ(push, pop, shift, unshift, splice λ“±)λŠ” μ—λŸ¬λ₯Ό λ˜μ§€λ©°, concat처럼 λŒ€μƒμ΄ λ°˜λ“œμ‹œ 배열이어야 ν•˜λŠ” κ²½μš°μ—λŠ” μ—λŸ¬κ°€ λ‚˜μ§€ μ•Šμ§€λ§Œ μ œλŒ€λ‘œ 된 κ²°κ³Όλ₯Ό 얻을 수 μ—†λ‹€.
  • ES6μ—μ„œλŠ” μœ μ‚¬λ°°μ—΄κ°μ²΄ λ˜λŠ” 순회 κ°€λŠ₯ν•œ λͺ¨λ“  μ’…λ₯˜μ˜ 데이터 νƒ€μž…μ„ λ°°μ—΄λ‘œ μ „ν™˜ν•˜λŠ” Array.from λ©”μ„œλ“œλ₯Ό μƒˆλ‘œ λ„μž…ν–ˆλ‹€.
var obj = {
0: 'a',
1: 'b',
2: 'c',
length: 3,
};

var arr = Array.from(obj);
console.log(arr); // ['a', 'b', 'c']

🐢 μƒμ„±μž λ‚΄λΆ€μ—μ„œ λ‹€λ₯Έ 생성사λ₯Ό ν˜ΈμΆœβ€‹

  • μƒμ„±μž 내뢀에 λ‹€λ₯Έ μƒμ„±μžμ™€ κ³΅ν†΅λœ λ‚΄μš©μ΄ μžˆμ„ 경우 call λ˜λŠ” applyλ₯Ό μ΄μš©ν•΄ λ‹€λ₯Έ μƒμ„±μžλ₯Ό ν˜ΈμΆœν•˜λ©΄ κ°„λ‹¨ν•˜κ²Œ λ°˜λ³΅μ„ 쀄일 수 μžˆλ‹€.
function Person(name, gender) {
this.name = name;
this.gender = gender;
}

function Student(name, gender, school) {
Person.call(this, name, gender);
this.school = school;
}

function Employee(name, gender, company) {
Person.apply(this, [name, gender]);
this.company = company;
}

var by = new Student('보영', 'female', 'λ‹¨κ΅­λŒ€');
var jn = new Employee('μž¬λ‚œ', 'male', 'ꡬ골');

🐢 μ—¬λŸ¬ 인수λ₯Ό λ¬Άμ–΄ ν•˜λ‚˜μ˜ λ°°μ—΄λ‘œ μ „λ‹¬ν•˜κ³  싢을 λ•Œ - apply ν™œμš©β€‹

  • 예λ₯Ό λ“€μ–΄, λ°°μ—΄μ—μ„œ μ΅œλŒ€/μ΅œμ†Ÿκ°’μ„ ꡬ해야 ν•  경우 applyλ₯Ό μ‚¬μš©ν•˜λ©΄ λ‹€μŒκ³Ό 같이 ꡬ할 수 μžˆλ‹€.
var numbers = [10, 20, 3, 16, 45];
var max = Math.max.apply(null, numbers);
var min = Math.min.apply(null, numbers);
console.log(max, min); // 45 3
  • ES6μ—μ„œλŠ” μŠ€ν”„λ ˆλ“œ μ—°μ‚°μžλ₯Ό μ΄μš©ν•˜λ©΄ κ°„λ‹¨ν•˜κ²Œ μž‘μ„±ν•  수 μžˆλ‹€.
const numbers = [10, 20, 3, 16, 45];
const max = Math.max(...numbers);
const min = Math.min(...numbers);
console.log(max, min); // 45 3
  • call/apply λ©”μ„œλ“œλŠ” λͺ…μ‹œμ μœΌλ‘œ thisλ₯Ό λ°”μΈλ”©ν•˜λ©΄μ„œ ν•¨μˆ˜ λ˜λŠ” λ©”μ„œλ“œλ₯Ό μ‹€ν–‰ν•˜λŠ” λ°©λ²•μ΄μ§€λ§Œ 이둜 인해 thisλ₯Ό μ˜ˆμΈ‘ν•˜κΈ° μ–΄λ €μ›Œ μ½”λ“œ 해석을 λ°©ν•΄ν•œλ‹€λŠ” 단점이 μžˆλ‹€.

🎈 bind λ©”μ„œλ“œβ€‹

Function.prototype.bind(thisArg[, arg1[, arg2[, ...]]])
  • bind λ©”μ„œλ“œλŠ” ES5μ—μ„œ μΆ”κ°€λœ κΈ°λŠ₯으둜, callκ³Ό λΉ„μŠ·ν•˜μ§€λ§Œ μ¦‰μ‹œ ν˜ΈμΆœν•˜μ§€λŠ” μ•Šκ³  λ„˜κ²¨λ°›μ€ this 및 μΈμˆ˜λ“€μ„ λ°”νƒ•μœΌλ‘œ μƒˆλ‘œμš΄ ν•¨μˆ˜λ₯Ό λ°˜ν™˜ν•˜κΈ°λ§Œ ν•˜λŠ” λ©”μ„œλ“œμ΄λ‹€.
  • λ‹€μ‹œ μƒˆλ‘œμš΄ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  λ•Œ 인수λ₯Ό λ„˜κΈ°λ©΄ κ·Έ μΈμˆ˜λ“€μ€ κΈ°μ‘΄ bind λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•  λ•Œ μ „λ‹¬ν–ˆλ˜ μΈμˆ˜λ“€μ˜ 뒀에 μ΄μ–΄μ„œ λ“±λ‘λœλ‹€. 즉 bind λ©”μ„œλ“œλŠ” ν•¨μˆ˜μ— thisλ₯Ό 미리 μ μš©ν•˜λŠ” 것과 λΆ€λΆ„ 적용 ν•¨μˆ˜λ₯Ό κ΅¬ν˜„ν•˜λŠ” 두 가지 λͺ©μ μ„ λͺ¨λ‘ μ§€λ‹Œλ‹€.
var func = function(a, b, c, d) {
console.log(this, a, b, c, d);
};

func(1, 2, 3, 4); // Window{ ... } 1 2 3 4

var bindFunc1 = func.bind({ x: 1 });
bindFunc1(5, 6, 7, 8); // { x: 1 } 5 6 7 8

var bindFunc2 = func.bind({ x: 1 }, 4, 5); // λΆ€λΆ„ 적용 ν•¨μˆ˜
bindFunc2(6, 7); // { x: 1 } 4 5 6 7
bindFunc2(8, 9); // { x: 1 } 4 5 8 9

🐢 name ν”„λ‘œνΌν‹°β€‹

  • bind λ©”μ„œλ“œλ₯Ό μ μš©ν•΄μ„œ μƒˆλ‘œ λ§Œλ“  ν•¨μˆ˜λŠ” name ν”„λ‘œνΌν‹°μ— 동사 bind의 μˆ˜λ™νƒœμΈ boundλΌλŠ” 접두어가 λΆ™λŠ”λ‹€. μ–΄λ–€ ν•¨μˆ˜μ˜ name ν”„λ‘œνΌν‹°κ°€ bound xxx라면 μ΄λŠ” 곧 ν•¨μˆ˜λͺ…이 xxx인 원본 ν•¨μˆ˜μ— bind λ©”μ„œλ“œλ₯Ό μ μš©ν•œ μƒˆλ‘œμš΄ ν•¨μˆ˜λΌλŠ” μ˜λ―Έκ°€ λ˜λ―€λ‘œ 기쑴의 callμ΄λ‚˜ apply보닀 μ½”λ“œλ₯Ό μΆ”μ ν•˜κΈ°μ— 더 μˆ˜μ›”ν•΄μ§„ 면이 μžˆλ‹€.
var func = function(a, b, c, d) {
console.log(this, a, b, c, d);
};

var bindFunc = func.bind({ x: 1}, 4, 5);
console.log(func.name); // func
console.log(bindFunc.name); // bound func

🐢 μƒμœ„ μ»¨ν…μŠ€νŠΈμ˜ thisλ₯Ό λ‚΄λΆ€ ν•¨μˆ˜λ‚˜ 콜백 ν•¨μˆ˜μ— μ „λ‹¬ν•˜κΈ°β€‹

  • λ©”μ„œλ“œμ˜ λ‚΄λΆ€ν•¨μˆ˜μ—μ„œ λ©”μ„œλ“œμ˜ thisλ₯Ό κ·ΈλŒ€λ‘œ λ°”λΌλ³΄κ²Œ ν•˜κΈ° μœ„ν•œ λ°©λ²•μœΌλ‘œ selfλ“±μ˜ λ³€μˆ˜λ₯Ό ν™œμš©ν•œ μš°νšŒλ²•μ΄ μžˆμ—ˆλŠ”λ°, call, apply λ˜λŠ” bind λ©”μ„œλ“œλ₯Ό μ΄μš©ν•˜λ©΄ 더 κΉ”λ”ν•˜κ²Œ μ²˜λ¦¬ν•  수 μžˆλ‹€.
// call
var obj = {
outer: function() {
console.log(this);

var innerFunc = function() {
console.log(this);
};

innerFunc.call(this);
},
};

obj.outer();

// bind
var obj = {
outer: function() {
console.log(this);

var innerFunc = function() {
console.log(this);
}.bind(this);

innerFunc();
},
};

obj.outer();
  • λ˜ν•œ 콜백 ν•¨μˆ˜λ₯Ό 인자둜 λ°›λŠ” ν•¨μˆ˜λ‚˜ λ©”μ„œλ“œ μ€‘μ—μ„œ 기본적으둜 콜백 ν•¨μˆ˜ λ‚΄μ—μ„œμ˜ this에 κ΄€μ—¬ν•˜λŠ” ν•¨μˆ˜ λ˜λŠ” λ©”μ„œλ“œμ— λŒ€ν•΄μ„œλ„ bind λ©”μ„œλ“œλ₯Ό μ΄μš©ν•˜λ©΄ this 값을 μ‚¬μš©μžμ˜ μž…λ§›μ— 맞게 λ°”κΏ€ 수 μžˆλ‹€.
var obj = {
logThis: function() {
console.log(this);
},
logThisLater1: function() {
setTimeout(this.logThis, 500);
},
logThisLater2: function() {
setTimeout(this.logThis.bind(this), 1000);
},
};

obj.logThisLater1(); // Window { ... }
obj.logThisLater2(); // obj { logThis: f, ... }

🎈 ν™”μ‚΄ν‘œ ν•¨μˆ˜μ˜ μ˜ˆμ™Έμ‚¬ν•­β€‹

  • ES6μ—μ„œ λ„μž…λœ ν™”μ‚΄ν‘œ ν•¨μˆ˜λŠ” μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ 생성 μ‹œ thisλ₯Ό λ°”μΈλ”©ν•˜λŠ” 과정이 μ œμ™Έλλ‹€. 즉 이 ν•¨μˆ˜ λ‚΄λΆ€μ—λŠ” thisκ°€ μ•„μ˜ˆ μ—†μœΌλ©°, μ ‘κ·Όν•˜κ³ μž ν•˜λ©΄ μŠ€μ½”ν”„μ²΄μΈμƒ κ°€μž₯ κ°€κΉŒμš΄ this에 μ ‘κ·Όν•˜κ²Œ λœλ‹€.
var obj = {
outer: function() {
console.log(this);

var innerFunc = () => {
console.log(this);
};

innerFunc();
},
};

obj.outer();
// outer { f }
// outer { f }

🎈 λ³„λ„μ˜ 인자둜 thisλ₯Ό λ°›λŠ” 경우(콜백 ν•¨μˆ˜ λ‚΄μ—μ„œμ˜ this)​

  • 콜백 ν•¨μˆ˜λ₯Ό 인자둜 λ°›λŠ” λ©”μ„œλ“œ 쀑 μΌλΆ€λŠ” μΆ”κ°€λ‘œ thisλ₯Ό 지정할 객체(thisArg)λ₯Ό 인자둜 지정할 수 μžˆλŠ” κ²½μš°κ°€ μžˆλ‹€. μ΄λŸ¬ν•œ λ©”μ„œλ“œμ˜ thisArg 값을 μ§€μ •ν•˜λ©΄ 콜백 ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ this값을 μ›ν•˜λŠ” λŒ€λ‘œ λ³€κ²½ν•  수 μžˆλ‹€.
  • 이런 ν˜•νƒœλŠ” λ‚΄λΆ€ μš”μ†Œμ— λŒ€ν•΄ 같은 λ™μž‘μœΌλ‘œ 반볡 μˆ˜ν–‰ν•΄μ•Ό ν•˜λŠ” λ°°μ—΄ λ©”μ„œλ“œμ— 많이 포진돼 있으며, 같은 이유둜 ES6μ—μ„œ μƒˆλ‘œ λ“±μž₯ν•œ Set, Map λ“±μ˜ λ©”μ„œλ“œμ—λ„ 일뢀 μ‘΄μž¬ν•œλ‹€.
var report = {
sum: 0,
count: 0,
add: function() {
var args = Array.prototype.slice.call(arguments);

args.forEach(function(entry) {
this.sum += entry;
++this.count;
}, this);
},
average: function () {
return this.sum / this.count;
},
};

report.add(60, 85, 95);
console.log(report.sum, report.count, report.average()); // 240 3 80
  • 배열을 μˆœνšŒν•˜λ©΄μ„œ 콜백 ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•˜λŠ”λ°, μ΄λ•Œ 콜백 ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œμ˜ thisλŠ” forEach ν•¨μˆ˜μ˜ 두 번째 인자둜 전달해쀀 thisκ°€ 바인딩 λœλ‹€.
  • 콜백 ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œμ˜ thisλŠ” add λ©”μ„œλ“œμ—μ„œμ˜ thisκ°€ μ „λ‹¬λœ μƒνƒœμ΄λ―€λ‘œ addλ©”μ„œλ“œμ˜ this(report)λ₯Ό κ·ΈλŒ€λ‘œ 가리킀고 μžˆλ‹€. λ”°λΌμ„œ μ„Έ μš”μ†Œλ₯Ό μˆœν•΄ν•˜λ©΄μ„œ report.sumκ°’ 및 report.count 값이 μ°¨λ‘€λ‘œ 바뀐닀.
  • 이 밖에도 thisArgλ₯Ό 인자둜 λ°›λŠ” λ©”μ„œλ“œλŠ” κ½€ 많이 μžˆλ‹€.
Array.prototype.forEach(callback[, thisArg])
Array.prototype.map(callback[, thisArg])
Array.prototype.filter(callback[, thisArg])
Array.prototype.some(callback[, thisArg])
Array.prototype.every(callback[, thisArg])
Array.prototype.find(callback[, thisArg])
Array.prototype.findIndex(callback[, thisArg])
Array.prototype.flatMap(callback[, thisArg])
Array.prototype.from(callback[, thisArg])
Set.prototype.forEach(callback[, thisArg])
Map.prototype.forEach(callback[, thisArg])

πŸ“š 정리​

  • λ‹€μŒ κ·œμΉ™μ€ λͺ…μ‹œμ  this 바인딩이 μ—†λŠ” ν•œ 늘 μ„±λ¦½ν•œλ‹€.
    • μ „μ—­κ³΅κ°„μ—μ„œμ˜ thisλŠ” 전역객체(λΈŒλΌμš°μ € window, Node.js global)λ₯Ό μ°Έμ‘°ν•œλ‹€.
    • μ–΄λ–€ ν•¨μˆ˜λ₯Ό λ©”μ„œλ“œλ‘œμ„œ ν˜ΈμΆœν•œ 경우 thisλŠ” λ©”μ„œλ“œ 호좜 주체(λ©”μ„œλ“œλͺ… μ•žμ˜ 객체)λ₯Ό μ°Έμ‘°ν•œλ‹€.
    • μ–΄λ–€ ν•¨μˆ˜λ₯Ό ν•¨μˆ˜λ‘œμ¨ ν˜ΈμΆœν•œ 경우 thisλŠ” 전역객체λ₯Ό μ°Έμ‘°ν•œλ‹€. λ©”μ„œλ“œμ˜ λ‚΄λΆ€ν•¨μˆ˜μ—μ„œλ„ κ°™λ‹€.
    • 콜백 ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œμ˜ thisλŠ” ν•΄λ‹Ή 콜백 ν•¨μˆ˜μ˜ μ œμ–΄κΆŒμ„ λ„˜κ²¨λ°›λŠ” ν•¨μˆ˜κ°€ μ •μ˜ν•œ 바에 λ”°λ₯΄λ©°, μ •μ˜ν•˜μ§€ μ•Šμ€ κ²½μš°μ—λŠ” 전역객체λ₯Ό μ°Έμ‘°ν•œλ‹€.
    • μƒμ„±μž ν•¨μˆ˜μ—μ„œμ˜ thisλŠ” 생성될 μΈμŠ€ν„΄μŠ€λ₯Ό μ°Έμ‘°ν•œλ‹€.
  • λ‹€μŒμ€ λͺ…μ‹œμ  this 바인딩이닀.
    • call, apply λ©”μ„œλ“œλŠ” thisλ₯Ό λͺ…μ‹œμ μœΌλ‘œ μ§€μ •ν•˜λ©΄μ„œ ν•¨μˆ˜ λ˜λŠ” λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œλ‹€.
    • bind λ©”μ„œλ“œλŠ” this 및 ν•¨μˆ˜μ— λ„˜κΈΈ 인수λ₯Ό 일뢀 μ§€μ •ν•΄μ„œ μƒˆλ‘œμš΄ ν•¨μˆ˜λ₯Ό λ§Œλ“ λ‹€.
    • μš”μ†Œλ₯Ό μˆœνšŒν•˜λ©΄μ„œ 콜백 ν•¨μˆ˜λ₯Ό 반볡 ν˜ΈμΆœν•˜λŠ” λ‚΄μš©μ˜ 일뢀 λ©”μ„œλ“œλŠ” λ³„λ„μ˜ 인자둜 thisλ₯Ό 받기도 ν•œλ‹€.