[TIL] 220108

Lee Syong·2022년 1ė›” 8ėž
0

TIL

ëŠĐ록 ëģīęļ°
143/204
post-thumbnail

📝 ė˜Ī늘 한 ęēƒ

  1. ė‹Ī행 ėŧĻ텍ėŠĪíŠļ

  2. this


📖 학ėŠĩ ėžëĢŒ

  1. ėą… 『ė―”ė–ī ėžë°”ėŠĪ큎ëĶ―íŠļ』

📚 ë°°ėšī ęēƒ

2. ė‹Ī행 ėŧĻ텍ėŠĪíŠļ

1) ė‹Ī행 ėŧĻ텍ėŠĪíŠļ란?

ė‹Ī행 ėŧĻ텍ėŠĪíŠļ란 ė‹Ī행할 ė―”ë“œė— ė œęģĩ할 환ęē― ė •ëģīë“Īė„ ëŠĻė•„놓ė€ 객ėēīëĨž 말한ë‹Ī.
동ėží•œ 환ęē―ė— ėžˆëŠ” ė―”ë“œë“Īė„ ė‹Ī행할 때 필ėš”í•œ 환ęē― ė •ëģīë“Īė„ ëŠĻė•„ ėŧĻ텍ėŠĪíŠļëĨž ęĩŽė„ąí•˜ęģ , ėīëĨž ė―œ ėŠĪ택ė— ėŒ“ė•„ ė˜Žë ļë‹Ī가, 가ėžĨ ėœ„ė— ėŒ“ė—ŽėžˆëŠ” ėŧĻ텍ėŠĪíŠļė™€ ęī€ë Ļ ėžˆëŠ” ė―”ë“œë“Īė„ ė‹Ī행하는 ė‹ėœžëĄœ ė „ėēī ė―”ë“œė˜ 환ęē―ęģž ėˆœė„œëĨž ëģīėžĨ한ë‹Ī.

'동ėží•œ 환ęē―', ėĶ‰ 하나ė˜ ė‹Ī행 ėŧĻ텍ėŠĪíŠļëĨž ęĩŽė„ąí•˜ëŠ” ë°Đëē•ėœžëĄœ ėžë™ėœžëĄœ ėƒė„ąë˜ëŠ” ė „ė—­ ęģĩ간ęģž eval() í•Ļėˆ˜, í•Ļėˆ˜ ę·ļëĶŽęģ  ëļ”록(ES6ė—ė„œ ėķ”ę°€)ėī ėžˆë‹Ī.

ė‹Ī행 ėŧĻ텍ėŠĪíŠļ는 variableEnvironment, LexicalEnvironment, ThisBindingėī띾는 ė„ļ 가ė§€ ė •ëģīëĨž ėˆ˜ė§‘í•œë‹Ī.

2) variableEnvironment

ė‹Ī행 ėŧĻ텍ėŠĪíŠļëĨž ėƒė„ąí•  때 varaibleEnvironmentė—ëŠ” 현ėžŽ ėŧĻ텍ėŠĪíŠļ ë‚īė˜ ė‹ëģ„ėžë“Īė— 대한 ė •ëģī(environmentRecord)ė™€ ė™ļëķ€ 환ęē― ė •ëģī(outerEnvironmentReference)가 ë‹īęļīë‹Ī.
ëģ€ęē― ė‚Ží•­ė€ 반ė˜ë˜ė§€ ė•ŠëŠ”ë‹Ī.

3) LexicalEnvironment

ė‹Ī행 ėŧĻ텍ėŠĪíŠļëĨž ėƒė„ąí•  때 variableEnvironmentė— ė •ëģīëĨž ëĻžė € ë‹īė€ ë‹ĪėŒ, ėīëĨž ę·ļ대로 ëģĩė‚Ží•ī LexicalEnvironmentëĨž 만ë“Īęģ , ėī후ė—ëŠ” LexicalEnvironmentëĨž ėĢžëĄœ ėīėšĐ하ęēŒ 된ë‹Ī.
ëģ€ęē― ė‚Ží•­ėī ė‹Īė‹œę°„ėœžëĄœ 반ė˜ëœë‹Ī.

(1) environmentRecord

environmentRecordė—ëŠ” 현ėžŽ ėŧĻ텍ėŠĪíŠļė™€ ęī€ë Ļ된 ė―”ë“œė˜ ė‹ëģ„ėž ė •ëģīë“Ī(ë§Ī개ëģ€ėˆ˜ëŠ…, ëģ€ėˆ˜ė˜ ė‹ëģ„ėž, ė„ ė–ļ한 í•Ļėˆ˜ė˜ í•Ļėˆ˜ëŠ… 등)ė„ ėˆ˜ė§‘í•œë‹Ī.
ėī는 ė―”ë“œę°€ ė‹Ī행되ęļ° ė „ė— ėžė–ī나는 ęģžė •ėœžëĄœ ėžë°”ėŠĪ큎ëĶ―íŠļ ė—”ė§„ė€ ė‹Īė œëĄœ ė―”ë“œę°€ ė‹Ī행되ęļ° ė „ė— ėīëŊļ í•īë‹đ 환ęē―ė— ė†í•œ ė―”ë“œė˜ ëģ€ėˆ˜ëŠ…ė„ ëŠĻ두 ė•Œęģ  ėžˆęēŒ 된ë‹Ī.

ė—Žęļ°ė„œ í˜ļėīėŠĪ팅ėī란 개념ėī 등ėžĨ한ë‹Ī.
ėžë°”ėŠĪ큎ëĶ―íŠļ ė—”ė§„ė€ ė‹ëģ„ėžë“Īė„ ėĩœėƒë‹ĻėœžëĄœ 끌ė–īė˜Žë Ī놓ė€ ë‹ĪėŒ ė‹Īė œ ė―”ë“œëĨž ė‹Ī행하는 ęēƒėīë‹Ī.

ë§Ī개ëģ€ėˆ˜ė™€ ëģ€ėˆ˜ė— 대한 í˜ļėīėŠĪ팅

environmentRecord는 현ėžŽ ė‹Ī행될 ėŧĻ텍ėŠĪíŠļė˜ 대ėƒ ė―”ë“œ ë‚īė— ė–īë–Ī ė‹ëģ„ėžë“Īėī ėžˆëŠ”ė§€ė—ë§Œ ęī€ė‹Žėī ėžˆęģ , 각 ė‹ëģ„ėžė— ė–īë–Ī 값ėī 할ë‹đ될 ęēƒėļė§€ëŠ” ęī€ė‹Žėī ė—†ë‹Ī.
따띾ė„œ, ëģ€ėˆ˜ëĨž í˜ļėīėŠĪ팅할 때 ëģ€ėˆ˜ëŠ…만 끌ė–īė˜ŽëĶŽęģ , 할ë‹đ ęģžė •ė€ ė›ëž˜ ėžëĶŽė— ę·ļ대로 ë‚ĻęēĻ둔ë‹Ī.

í•Ļėˆ˜ ė„ ė–ļė˜ í˜ļėīėŠĪ팅

ëģ€ėˆ˜ëŠ” ė„ ė–ļëķ€ė™€ 할ë‹đëķ€ëĨž 나누ė–ī ė„ ė–ļëķ€ë§Œ 끌ė–īė˜ŽëĶŽëŠ” 반ëĐī, í•Ļėˆ˜ 'ė„ ė–ļ'ė€ í•Ļėˆ˜ ė „ėēīëĨž 끌ė–īė˜ŽëĶ°ë‹Ī.

í•Ļėˆ˜ ė„ ė–ļëŽļęģž í•Ļėˆ˜ 표현ė‹

console.log(sum(1, 2));
console.log(multiply(3, 4));

// í•Ļėˆ˜ ė„ ė–ļëŽļ
function sum (a, b) {
  return a + b;
}

// í•Ļėˆ˜ 표현ė‹
var multiply = function (a, b) {
  return a * b;
}

í•Ļėˆ˜ 표현ė‹ėī란 í•Ļėˆ˜ëĨž ë‹ĪëĨļ ëģ€ėˆ˜ė— 값ėœžëĄœėĻ 할ë‹đ한 ęēƒė„ 말한ë‹Ī.

í•Ļėˆ˜ ė„ ė–ļëŽļęģž í•Ļėˆ˜ 표현ė‹ė€ í˜ļėīėŠĪ팅ė— ėžˆė–ī ę·đ멅한 ė°Ļėīė ė„ 가ė§„ë‹Ī.
í˜ļėīėŠĪ팅ė„ 마ėđœ ėƒíƒœëĨž ėž„ė˜ëĄœ ė―”ë“œëĄœėĻ 표현하ëĐī ë‹ĪėŒęģž 같ë‹Ī.

var sum = function sum (a, b) { // (í•Ļėˆ˜ ė„ ė–ļëŽļ) í•Ļėˆ˜ ė„ ė–ļëŽļ ė „ėēīëĨž í˜ļėīėŠĪ팅
  return a + b;
}

var multiply; // (í•Ļėˆ˜ 표현ė‹) ëģ€ėˆ˜ ė„ ė–ļëķ€(í•Ļėˆ˜ëĨž 할ë‹đ한 ëģ€ėˆ˜ëŠ…)만ė„ í˜ļėīėŠĪ팅

console.log(sum(1, 2));
console.log(multiply(3, 4));

multiply =function (a, b) { // (í•Ļėˆ˜ 표현ė‹) ëģ€ėˆ˜ 할ë‹đëķ€ëŠ” ė›ëž˜ ėžëĶŽė— ë‚ĻęēĻ둠
  return a * b;
}

따띾ė„œ, multiply(3, 4)ëĨž ėķœë Ĩ하ęģ ėž 할 때 ëģ€ėˆ˜ multiplyė—ëŠ” ė•„ė§ í•Ļėˆ˜ę°€ 할ë‹đ되ęļ° ė „ėīëŊ€ëĄœ 'multiply is not a function'ėī띾는 ė—ëŸŽę°€ 뜮ë‹Ī.

cf. ėƒëŒ€ė ėœžëĄœ í•Ļėˆ˜ ė„ ė–ļëŽļëģīë‹Ī í•Ļėˆ˜ 표현ė‹ė„ ė‚ŽėšĐ하는 ęēƒėī ė•ˆė „하ë‹Ī. í•Ļėˆ˜ ė„ ė–ļëŽļė€ í†ĩė§ļ로 í˜ļėīėŠĪ팅 되ęļ° 때ëŽļė— ëŽļė œę°€ ėƒęļļ 확ëĨ ėī 높ė€ 반ëĐī, í•Ļėˆ˜ 표현ė‹ė„ ė‚ŽėšĐ하ëĐī ëģ€ėˆ˜ëŠ…만 í˜ļėīėŠĪ팅 되ęļ° 때ëŽļė— ëģ€ėˆ˜ė— í•Ļėˆ˜ę°€ 할ë‹đ되ęļ° ė „ė— í•Ļėˆ˜ëĨž ė‹Ī행하ëĐī ė—ëŸŽëĨž 띄ė›ŒėĪŒėœžëĄœėĻ 더 큰 혾란ė„ ë°Đė§€í•  ėˆ˜ ėžˆë‹Ī.

(2) ėŠĪė―”프, ėŠĪė―”프 ėēīėļ, outerEnvironmentReference

ėŠĪė―”프란 ė‹ëģ„ėžė— 대한 ėœ íšĻëē”ėœ„ëĨž 말한ë‹Ī.
ES5ęđŒė§€ė˜ ėžë°”ėŠĪ큎ëĶ―íŠļ는 ė „ė—­ ęģĩ간ė„ ė œė™ļ하ëĐī ė˜Īė§ í•Ļėˆ˜ė— ė˜í•īė„œë§Œ ėŠĪė―”프가 ėƒė„ąëœë‹Ī.
(ES6ė—ė„œëŠ” ëļ”록ė— ė˜í•īė„œë„ ėŠĪė―”프 ęē―ęģ„ę°€ 발ėƒí•œë‹Ī.)

ėŠĪė―”프 ėēīėļėī란 ė‹ëģ„ėžė˜ ėœ íšĻëē”ėœ„ëĨž ė•ˆė—ė„œëķ€í„° 바ęđĨėœžëĄœ ė°Ļ례로 ęē€ėƒ‰í•ī나가는 ęēƒė„ 말한ë‹Ī.
ėīëĨž 가ëŠĨėž€ 하는 ęēƒėī LexicalEnvironmentė˜ 두 ëēˆė§ļ ėˆ˜ė§‘ ėžëĢŒėļ outerEnvironmentReferenceėīë‹Ī.
(ėēŦ ëēˆė§ļ ėˆ˜ė§‘ ėžëĢŒ: environmentRecord / 두 ëēˆė§ļ ėˆ˜ė§‘ ėžëĢŒ: outerEnvironmentReference)

var a = 1;
var outer = function () {
  var inner = function () {
    console.log(a);
    var a = 3;
  };
  inner();
  console.log(a);
};
outer();
console.log(a);

outerEnvironmentReference는 현ėžŽ í˜ļėķœëœ í•Ļėˆ˜ę°€ ė„ ė–ļ될 ë‹đė‹œė˜ LexicalEnvironment(ėĶ‰, 바로 ė§ė „ ėŧĻ텍ėŠĪíŠļė˜ LexicalEnvironment)ëĨž ė°ļėĄ°í•œë‹Ī.

  • ė „ė—­ ėŧĻ텍ėŠĪíŠļ ėžë™ėœžëĄœ ėƒė„ą
    ė „ė—­ ėŧĻ텍ėŠĪíŠļė˜ L.E
    e: { a, outer } (ė „ė—­ ėŧĻ텍ėŠĪíŠļ는 ė„ ė–ļ ė‹œė ėī 따로 ė—†ęļ° 때ëŽļė— outerEnvironmentReference는 ė—†ęģ  environmentRecord만 ėžˆë‹Ī.)
  • outer() í•Ļėˆ˜ ė‹Ī행 ė‹œ outer ė‹Ī행 ėŧĻ텍ėŠĪíŠļ 활ė„ąí™”
    outer ė‹Ī행 ėŧĻ텍ėŠĪíŠļė˜ L.E
    e: { inner }
    o: GLOBAL L.E ( = outer() í•Ļėˆ˜ę°€ ė„ ė–ļ된 ë‹đė‹œė˜ L.E )
  • inner() í•Ļėˆ˜ ė‹Ī행 ė‹œ inner ė‹Ī행 ėŧĻ텍ėŠĪíŠļ 활ė„ąí™”
    inner ė‹Ī행 ėŧĻ텍ėŠĪíŠļė˜ L.E
    e: { a }
    o: outer L.E ( = inner() í•Ļėˆ˜ę°€ ė„ ė–ļ된 ë‹đė‹œė˜ L.E )

따띾ė„œ, ėīėē˜ëŸž ė—ŽëŸŽ ėŠĪė―”프ė—ė„œ 동ėží•œ ė‹ëģ„ėžëĨž ė„ ė–ļ한 ęē―ėš°ė—ëŠ” ëŽīėĄ°ęąī ėŠĪė―”프 ėēīėļ ėƒė—ė„œ 가ėžĨ ëĻžė € 발ęēŽëœ ė‹ëģ„ėžė—ë§Œ ė ‘ę·žėī 가ëŠĨ하ë‹Ī.
ėŠĪė―”프 ėēīėļ ėƒė˜ ė–īë–Ī ėŠĪė―”프ė˜ LexicalEnvironmentė— ė°ū는 ė‹ëģ„ėžę°€ ėĄīėžŽí•œë‹ĪëĐī 더 ėīėƒ ėŠĪė―”프 ėēīėļ ęē€ėƒ‰ė„ ė§„행하ė§€ ė•Šęģ  ė°ūė€ ė‹ëģ„ėžė˜ 값ė„ 반환하ęēŒ 된ë‹Ī.
ėĶ‰, ėƒėœ„ ėŠĪė―”프ė˜ LexicalEnvironmentė— 같ė€ ė‹ëģ„ėžę°€ ėĄīėžŽí•˜ë”띞도 ė ‘ę·ží•  ėˆ˜ ė—†ë‹Ī.
ėīëĨž ëģ€ėˆ˜ ė€ë‹‰í™”띞ęģ  한ë‹Ī.

ėī때 ė „ė—­ ėŧĻ텍ėŠĪíŠļė˜ LexicalEnvironmentė— ë‹īęļī ëģ€ėˆ˜ëĨž ė „ė—­ëģ€ėˆ˜ëžęģ  하ęģ , ę·ļ 밖ė˜ í•Ļėˆ˜ė— ė˜í•ī ėƒė„ąëœ ė‹Ī행 ėŧĻ텍ėŠĪíŠļė˜ ëģ€ėˆ˜ë“Īė„ ė§€ė—­ëģ€ėˆ˜ëžęģ  한ë‹Ī.

4) this

마ė§€ë§‰ėœžëĄœ, ė‹Ī행 ėŧĻ텍ėŠĪíŠļė˜ thisBindingė—ëŠ” this로 ė§€ė •ëœ 객ėēī가 ė €ėžĨ된ë‹Ī.
this는 ė‹Ī행 ėŧĻ텍ėŠĪíŠļ 활ė„ąí™” ë‹đė‹œė— ė§€ė •ë˜ęģ , í•Ļėˆ˜ëĨž í˜ļėķœí•˜ëŠ” ë°Đëē•ė— 따띾 ę·ļ 값ėī 닮띾ė§„ë‹Ī.
만ė•― ė‹Ī행 ėŧĻ텍ėŠĪíŠļ 활ė„ąí™” ë‹đė‹œė— this가 ė§€ė •ë˜ė§€ ė•Šė•˜ë‹ĪëĐī, thisė—ëŠ” ė „ė—­ 객ėēī가 ė €ėžĨ된ë‹Ī.


3. this

1) ėƒí™Đė— 따띾 닮띾ė§€ëŠ” this â‘Ī

대ëķ€ëķ„ė˜ 객ėēīė§€í–Ĩ ė–ļė–īė—ė„œ this는 íī래ėŠĪ로 ėƒė„ąí•œ ėļėŠĪí„īėŠĪ 객ėēīëĨž ė˜ëŊļ한ë‹Ī.
ę·ļ럮나, ėžë°”ėŠĪ큎ëĶ―íŠļė—ė„œė˜ this는 ė–ī디ė„œë“  ė‚ŽėšĐ할 ėˆ˜ ėžˆė–ī 혾란ė„ ė•žęļ°í•œë‹Ī.

ėžë°”ėŠĪ큎ëĶ―íŠļė—ė„œ this는 ęļ°ëģļė ėœžëĄœ ė‹Ī행 ėŧĻ텍ėŠĪíŠļ가 ėƒė„ąë  때(ėĶ‰, í•Ļėˆ˜ę°€ í˜ļėķœë  때) ęē°ė •ëœë‹Ī.
í•Ļėˆ˜ëĨž ė–īë–Ī ë°Đė‹ėœžëĄœ í˜ļėķœí•˜ëŠëƒė— 따띾 ę·ļ 값ėī 닮띾ė§„ë‹Ī.

(1) ė „ė—­ ęģĩ간ė—ė„œė˜ this

ė „ė—­ ęģĩ간ė—ė„œė˜ this는 ė „ė—­ 객ėēī(ëļŒëžėš°ė €ė—ė„œëŠ” window, Node.jsė—ė„œëŠ” global)ė„ 가ëĶŽí‚Ļë‹Ī.

cf. ė „ė—­ ëģ€ėˆ˜ė™€ ė „ė—­ 객ėēīė˜ 프로퍾티

ė „ė—­ ëģ€ėˆ˜ëĨž ė„ ė–ļ하ëĐī, ėžë°”ėŠĪ큎ëĶ―íŠļ ė—”ė§„ė€ ėīëĨž ė „ė—­ 객ėēīė˜ 프로퍾티로 할ë‹đ한ë‹Ī.
ė‚Žė‹Ī ėžë°”ėŠĪ큎ëĶ―íŠļė˜ ëŠĻ든 ëģ€ėˆ˜ëŠ” íŠđė • 객ėēīė˜ 프로퍾티로ė„œ 동ėž‘í•œë‹Ī.
ėī때 íŠđė • 객ėēī란 ė‹Ī행 ėŧĻ텍ėŠĪíŠļė˜ LexicalEnvironmentëĨž 말한ë‹Ī.

따띾ė„œ, 대ëķ€ëķ„ė˜ ęē―ėš° ė „ė—­ ėŧĻ텍ėŠĪíŠļė—ė„œëŠ” var로 ëģ€ėˆ˜ëĨž ė„ ė–ļ하는 ęēƒęģž windowė˜ 프로퍾티ė— ė§ė ‘ 할ë‹đ하는 ęēƒė€ 똑같ėī 동ėž‘í•œë‹Ī.
ę·ļ럮나, 객ėēīė˜ 프로퍾티ëĨž ė œęą°í•˜ëŠ” 'delete ė—°ė‚°ėž'는 ė „ėžė˜ ęē―ėš°ė—ëŠ” ė œëŒ€ëĄœ ėž‘동하ė§€ ė•ŠëŠ”ë‹Ī.
ė „ė—­ ëģ€ėˆ˜ëĨž ė„ ė–ļ하ëĐī ėžë°”ėŠĪ큎ëĶ―íŠļ ė—”ė§„ėī ėīëĨž ėžë™ėœžëĄœ ė „ė—­ 객ėēīė˜ 프로퍾티로 할ë‹đ하ė§€ë§Œ, ėķ”ę°€ëĄœ í•īë‹đ 프로퍾티ė˜ configurable ė†ė„ą(ëģ€ęē― 및 ė‚­ė œ 가ëŠĨė„ą)ė„ false로 ė •ė˜í•˜ęļ° 때ëŽļėīë‹Ī.

console.log(window.c, this.c, c); // c is not defined

window.c = 3;

console.log(window.c, this.c, c); // 3 3 3
var c = 3;

delete c; // í˜đė€ delete window.c;

console.log(c, window.c, this.c); // 3 3 3 (delete ė—°ė‚°ėžę°€ ėž‘동 x)

ė •ëĶŽí•˜ėžëĐī, var로 ė„ ė–ļ한 ė „ė—­ ëģ€ėˆ˜ė™€ ė „ė—­ 객ėēīė˜ 프로퍾티는 í˜ļėīėŠĪ팅 ė—Žëķ€ 및 configurable ė—Žëķ€ė—ė„œ ė°ĻėīëĨž ëģīėļë‹Īęģ  할 ėˆ˜ ėžˆë‹Ī.

(2) ëДė„œë“œëĄœė„œ í˜ļėķœí•  때 ę·ļ ëДė„œë“œ ë‚īëķ€ė—ė„œė˜ this

ëДė„œë“œ ë‚īëķ€ė—ė„œė˜ this는 ëДė„œë“œ í˜ļėķœ ėĢžėēī(ëДė„œë“œëŠ… ė•žė˜ 객ėēī)ëĨž 가ëĶŽí‚Ļë‹Ī.

(3) í•Ļėˆ˜ëĄœė„œ í˜ļėķœí•  때 ę·ļ í•Ļėˆ˜ ë‚īëķ€ė—ė„œė˜ this

í•Ļėˆ˜ ë‚īëķ€ė—ė„œė˜ this

ęē°ëĄ ëķ€í„° 말하ėžëĐī, í•Ļėˆ˜ ë‚īëķ€ė—ė„œė˜ this는 ė „ė—­ 객ėēīëĨž 가ëĶŽí‚Ļë‹Ī.

ėœ„ė—ė„œ this는 ëДė„œë“œë‚˜ í•Ļėˆ˜ëĨž í˜ļėķœí•œ ėĢžėēīëĨž 가ëĶŽí‚Ļë‹Īęģ  했ë‹Ī.
ę·ļ런데 ëДė„œë“œė™€ 닮ëĶŽ í•Ļėˆ˜ëĄœė„œ í˜ļėķœí•˜ëŠ” ęēƒė€ í˜ļėķœ ėĢžėēīëĨž 멅ė‹œí•˜ė§€ ė•Šęģ  개발ėžę°€ ė―”ë“œė— ė§ė ‘ ęī€ė—Ží•īė„œ ė‹Ī행한 ęēƒėīęļ° 때ëŽļė— í˜ļėķœ ėĢžėēīė˜ ė •ëģīëĨž ė•Œ ėˆ˜ ė—†ë‹Ī.
ė•žė„œ ė‹Ī행 ėŧĻ텍ėŠĪíŠļëĨž 활ė„ąí™”í•  때(ėĶ‰, í•Ļėˆ˜ëĨž ė‹Ī행할 때) this가 ė§€ė •ë˜ė§€ ė•Šė€ ęē―ėš° this는 ė „ė—­ 객ėēīëĨž 가ëĶŽí‚Ļë‹Īęģ  했ėœžëŊ€ëĄœ, í•Ļėˆ˜ ë‚īëķ€ė—ė„œė˜ this는 ė „ė—­ 객ėēīëĨž 가ëĶŽí‚ĪęēŒ 되는 ęēƒėīë‹Ī.

ëДė„œë“œė˜ ë‚īëķ€ í•Ļėˆ˜ė—ė„œė˜ this

í—·ę°ˆëĶŽęļ° ė‰―ė§€ë§Œ 하나만 ė•ŒëĐī 된ë‹Ī.
ëДė„œë“œė˜ ë‚īëķ€ í•Ļėˆ˜ëĨž í•Ļėˆ˜ëĄœė„œ í˜ļėķœí–ˆëŠ”ė§€, ëДė„œë“œëĄœė„œ í˜ļėķœí–ˆëŠ”ė§€ë§Œ 파ė•…하ëĐī this 값ė„ ė •í™•ížˆ 맞ėķœ ėˆ˜ ėžˆë‹Ī.
ėĶ‰, this 바ėļë”Đė— ėžˆė–ī í•Ļėˆ˜ëĨž ė‹Ī행하는 ë‹đė‹œė˜ ėĢžëģ€ 환ęē―ė€ ėĪ‘ėš”하ė§€ ė•Šęģ , ė˜Īė§ í•īë‹đ í•Ļėˆ˜ëĨž í˜ļėķœí•˜ëŠ” ęĩŽëŽļ ė•žė— ė  또는 대ęī„í˜ļ 표ęļ°ę°€ ėžˆëŠ”ė§€ę°€ ęī€ęąīėī띞ęģ  할 ėˆ˜ ėžˆë‹Ī.

cf. í•Ļėˆ˜ę°€ ė‹Ī행될 때 ė‹Ī행 ėŧĻ텍ėŠĪíŠļ가 ėƒė„ąë˜ëĐīė„œ í˜ļėīėŠĪ팅, ėŠĪė―”프 ėēīėļ ėˆ˜ė§‘, this 바ėļë”Đ 등ė„ ėˆ˜í–‰í•œë‹Ī.

ę·ļ런데 ėī렇ęēŒ 하ëĐī thisė— 대한 ęĩŽëķ„ė€ 멅확히 할 ėˆ˜ ėžˆė§€ë§Œ, this띾는 ë‹Ļė–ī가 ėĢžëŠ” ėļėƒęģžëŠ” 닮띾ė ļ ëē„ë ļë‹Ī.
í˜ļėķœ ėĢžėēī가 ė—†ė„ 때 ėžë™ėœžëĄœ ė „ė—­ 객ėēīëĨž 바ėļë”Đ하ęļ°ëģīë‹Ļ, í˜ļėķœ ë‹đė‹œ ėĢžëģ€ 환ęē―ė˜ thisëĨž ę·ļ대로 ėƒė†ë°›ė•„ ė‚ŽėšĐ할 ėˆ˜ ėžˆë‹ĪëĐī 더 ėĒ‹ė„ ęēƒėīë‹Ī.

ðŸ’Ą ëДė„œë“œė˜ ë‚īëķ€ í•Ļėˆ˜ė—ė„œė˜ thisëĨž ėš°íšŒí•˜ëŠ” ë°Đëē•

ES5ęđŒė§€ëŠ” ėžėēīė ėœžëĄœ ë‚īëķ€ í•Ļėˆ˜ė— thisëĨž ėƒė†í•  ë°Đëē•ė€ ė—†ë‹Ī.
ë‹Ī만, ëģ€ėˆ˜ė— ėƒėœ„ ėŠĪė―”프ė˜ thisëĨž ė €ėžĨí•īė„œ ėīëĨž ë‚īëķ€ í•Ļėˆ˜ė—ė„œ 활ėšĐ하는 ė‹ėœžëĄœ thisëĨž ėš°íšŒí•  ėˆ˜ ėžˆë‹Ī.

var obj = {
  outer: function () {
    console.log(this); // obj
    var innerFunc1 = function () {
      console.log(this); // window
    };
    innerFunc1();
    
    var self = this; // outer í•Ļėˆ˜ę°€ í˜ļėķœë  ë‹đė‹œė˜ í˜ļėķœ ėĢžėēī = obj ( âˆĩ obj.outer(); )
    var innerFunc2 = function () {
      console.log(self); // obj
    };
    innerFunc2();
  }
};
obj.outer();

ėī밖ė—ë„ call / apply / bind ëДė„œë“œ 등ė„ ė‚ŽėšĐ하는 ë°Đëē•ėī ėžˆë‹Ī. ėīë“Īė€ ë’Īė—ė„œ ė‚īíŽīëģž ęēƒėīë‹Ī.

ðŸ’Ą 화ė‚ī표 í•Ļėˆ˜: thisëĨž 바ėļë”Đ하ė§€ ė•ŠëŠ” í•Ļėˆ˜

한íŽļ, ES6ė—ė„œëŠ” í•Ļėˆ˜ ë‚īëķ€ė—ė„œ this가 ė „ė—­ 객ėēīëĨž 가ëĶŽí‚Ī는 ëŽļė œëĨž ëģīė™„하ęģ ėž 화ė‚ī표 í•Ļėˆ˜ëĨž ėīėšĐ할 ėˆ˜ ėžˆë‹Ī.
화ė‚ī표 í•Ļėˆ˜ëŠ” ė‹Ī행 ėŧĻ텍ėŠĪíŠļëĨž ėƒė„ąí•  때 ė•„ė˜ˆ thisëĨž 바ėļë”Đ하ė§€ ė•Šęļ° 때ëŽļė— 화ė‚ī표 í•Ļėˆ˜ ë‚īëķ€ė—ëŠ” this가 ė•„ė˜ˆ ė—†ė–ī ėīė— ė ‘ę·ží•˜ë ĪëĐī ėŠĪė―”프ėēīėļėƒ 가ėžĨ 가ęđŒėšī thisė— ė ‘ę·ží•˜ęēŒ 된ë‹Ī.

(4) ė―œë°ą í•Ļėˆ˜ í˜ļėķœ ė‹œ ę·ļ í•Ļėˆ˜ ë‚īëķ€ė—ė„œė˜ this

setTimeout(function () { console.log(this) }, 300); // window

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

// addEventListener는 ėžėēīė ėœžëĄœ ė―œë°ą í•Ļėˆ˜ëĨž í˜ļėķœí•  때 ėžė‹ ė˜ thisëĨž ėƒė†í•˜ë„록 ė •ė˜ë˜ė–ī ėžˆë‹Ī
document.querySelector("button").addEventListener("click", function () {
  console.log(this); // <button>ëē„튞</button>
  
});

ė―œë°ą í•Ļėˆ˜ė—ė„œė˜ this는 í•īë‹đ ė―œë°ą í•Ļėˆ˜ė˜ ė œė–īęķŒė„ 넘ęēĻ받ė€ í•Ļėˆ˜(setTimeout, forEach, addEventListener 등)가 ė •ė˜í•œ 바ė— 따ëĨīëĐ°, ė •ė˜í•˜ė§€ ė•Šė€ ęē―ėš°ė—ëŠ” ė―œë°ą í•Ļėˆ˜ 또한 í•Ļėˆ˜ëĄœė„œ í˜ļėķœí•˜ëŠ” ęēƒėīęļ° 때ëŽļė— ė „ė—­ 객ėēīëĨž 가ëĶŽí‚ĪęēŒ 된ë‹Ī.

(5) ėƒė„ąėž í•Ļėˆ˜ ë‚īëķ€ė—ė„œė˜ this

ėƒė„ąėž í•Ļėˆ˜ ë‚īëķ€ė—ė„œė˜ this는 ėƒė„ąėžė— ė˜í•ī ęģ§ ėƒˆëĄœ 만ë“Īė–īė§ˆ 객ėēī, ėĶ‰ ėļėŠĪí„īėŠĪ가 된ë‹Ī.

cf. ėƒė„ąėž í•Ļėˆ˜ëŠ” ė–īë–Ī ęģĩí†ĩ된 ė„ąė§ˆė„ ė§€ë‹ˆëŠ” 객ėēīë“Īė„ ėƒė„ąí•˜ëŠ” 데 ė‚ŽėšĐ하는 í•Ļėˆ˜ėīë‹Ī.
객ėēīė§€í–Ĩ ė–ļė–īė—ė„œëŠ” ėƒė„ąėžëĨž íī래ėŠĪ, íī래ėŠĪëĨž í†ĩí•ī 만든 객ėēīëĨž ėļėŠĪí„īėŠĪ띞ęģ  한ë‹Ī.

2) 멅ė‹œė ėœžëĄœ thisëĨž 바ėļë”Đ하는 ë°Đëē•

(1) call ëДė„œë“œ

call ëДė„œë“œëŠ” í•īë‹đ ëДė„œë“œė˜ í˜ļėķœ ėĢžėēīėļ í•Ļėˆ˜ëĨž ėĶ‰ė‹œ ė‹Ī행하도록 하는 멅ë đėīë‹Ī.
call ëДė„œë“œė˜ ėēŦ ëēˆė§ļ ėļėžëĨž this로 바ėļë”Đ하ęģ , ėī후ė˜ ėļėžë“Īė„ í˜ļėķœí•  í•Ļėˆ˜ė˜ ë§Ī개ëģ€ėˆ˜ëĄœ 한ë‹Ī.

(2) apply ëДė„œë“œ

apply ëДė„œë“œ 또한 call ëДė„œë“œė™€ ęļ°ëŠĨė ėœžëĄœ ė™„ė „히 동ėží•˜ë‹Ī.
ë‹Ī만, apply ëДė„œë“œëŠ” call ëДė„œë“œė™€ 닮ëĶŽ 두 ëēˆė§ļ ėļėžëĨž 'ë°°ė—ī'로 받ė•„ ę·ļ ë°°ė—īė˜ ėš”ė†Œë“Īė„ í˜ļėķœí•  í•Ļėˆ˜ė˜ ë§Ī개ëģ€ėˆ˜ëĄœ ė§€ė •í•œë‹Ī는 ė ė—ė„œ ė°Ļėī가 ėžˆë‹Ī.

(3) call / apply ëДė„œë“œė˜ 활ėšĐ

ėœ ė‚Žë°°ė—ī객ėēīė— ë°°ė—ī ëДė„œë“œëĨž ė ėšĐ

ėœ ė‚Žë°°ė—ī객ėēī란 ① ë°°ė—īė˜ ęĩŽėĄ°ė™€ ėœ ė‚Ží•œ 객ėēī, ėĶ‰ í‚Ī가 0 또는 ė–‘ė˜ ė •ėˆ˜ėļ 프로퍾티가 ėĄīėžŽí•˜ęģ  length 프로퍾티ė˜ 값ėī 0 또는 ė–‘ė˜ ė •ėˆ˜ėļ 객ėēīëĨž 말한ë‹Ī.
② í•Ļėˆ˜ ë‚īëķ€ė—ė„œ ė ‘ę·ží•  ėˆ˜ ėžˆëŠ” arguments 객ėēī나 â‘Ē querySelectorAll, getElementsByClassName 등ė˜ Node ė„ íƒėžëĄœ ė„ íƒí•œ ęē°ęģžėļ NodeList도 ėœ ė‚Žë°°ė—ī객ėēīė— í•īë‹đ된ë‹Ī.

var str = "abc def";

var newArr = Array.prototype.map.call(str, function(char) { return char + "!"; });

console.log(newArr); // [ "a!", "b!", "c!", "!", "d!", "e!", "f!" ]

또한, â‘Ģ ë°°ė—īėē˜ëŸž ėļ덱ėŠĪė™€ length 프로퍾티ëĨž 가ė§€ëŠ” ëŽļėžė—īė— 대í•īė„œë„ ë°°ė—ī ëДė„œë“œëĨž ė ėšĐ할 ėˆ˜ ėžˆë‹Ī.
ë‹Ī만, ėī ęē―ėš°ė—ëŠ” ė›ëģļ ëŽļėžė—īė— ëģ€ęē―ė„ 가하는 ëДė„œë“œëŠ” ė ėšĐ할 ėˆ˜ ė—†ë‹Ī.

ę·ļ런데 ė‚Žė‹Ī call/applyëĨž ėīėšĐí•ī 형ëģ€í™˜ė„ 하는 ęēƒė€ 'thisëĨž ė›í•˜ëŠ” 값ėœžëĄœ ė§€ė •í•īė„œ í˜ļėķœí•œë‹Ī'띾는 ëģļ래 ëДė„œë“œė˜ ė˜ë„ė™€ëŠ” ë‹Īė†Œ 동ë–Ļė–īė§„ 활ėšĐëē•ėī띞ęģ  할 ėˆ˜ ėžˆë‹Ī.
ėīė— ES6ė—ė„œëŠ” ėœ ė‚Žë°°ė—ī객ėēī 또는 ėˆœíšŒ 가ëŠĨ한 ëŠĻ든 ėĒ…ëĨ˜ė˜ 데ėī터 타ėž…ė„ ë°°ė—ī로 ė „환하는 Array.from() ëДė„œë“œëĨž 도ėž…í–ˆë‹Ī.

ėƒė„ąėž ë‚īëķ€ė—ė„œ ë‹ĪëĨļ ėƒė„ąėžëĨž í˜ļėķœ

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

function Student(name, gender, school) {
  Person.call(this, name, gender); // this는 'syong'ëĨž 가ëĶŽí‚Ļë‹Ī
  this.school = school;
}

var syong = new Student("ėˆ‘", "female", "대학ęĩ");

ėƒė„ąėž í•Ļėˆ˜ ë‚īëķ€ė—ė„œ ë‹ĪëĨļ ėƒė„ąėž í•Ļėˆ˜ëĨž í˜ļėķœí•˜ė—Ž ėļėŠĪí„īėŠĪė˜ ė†ė„ąė„ ė •ė˜í•ĻėœžëĄœėĻ 반ëģĩė„ ėĪ„ėž ėˆ˜ ėžˆë‹Ī.

ė—ŽëŸŽ ėļėˆ˜ëĨž ëŽķė–ī 하나ė˜ ë°°ė—ī로 ė „닎하ęģ  ė‹ķė„ 때 - apply 활ėšĐ

var numbers = [10, 20, 3, 16, 45];
var max = Math.max.apply(null, numbers);
console.log(max); // 45

ė—ŽëŸŽ 개ė˜ ėļėˆ˜ëĨž 받는 ëДė„œë“œė—, 하나ė˜ ë°°ė—ī로 ėļėˆ˜ë“Īė„ ė „닎하ęģ  ė‹ķė„ 때, apply ëДė„œë“œëĨž 활ėšĐ할 ėˆ˜ ėžˆë‹Ī.

(4) bind ëДė„œë“œ

bind ëДė„œë“œëŠ” call ëДė„œë“œė™€ ëđ„ėŠ·í•˜ė§€ë§Œ í•īë‹đ ëДė„œë“œė˜ í˜ļėķœ ėĢžėēīėļ í•Ļėˆ˜ëĨž ėĶ‰ė‹œ í˜ļėķœí•˜ė§€ëŠ” ė•Šęģ  넘ęēĻ 받ė€ this 및 ėļėˆ˜ë“Īė„ 바탕ėœžëĄœ ėƒˆëĄœėšī í•Ļėˆ˜ëĨž 반환한ë‹Ī.
ėī는 thisëĨž ė§€ė •í•  ëŋ ė•„니띞 ëķ€ëķ„ ė ėšĐ í•Ļėˆ˜ëĨž ęĩŽí˜„하ęļ° ėœ„í•īė„œë„ ė‚ŽėšĐ된ë‹Ī.

name 프로퍾티

call/apply ëДė„œë“œëŠ” 멅ė‹œė ėœžëĄœ ëģ„도ė˜ thisëĨž 바ėļë”Đ하는 ë°Đëē•ėīė§€ë§Œ ė˜Ī히ë Ī ėī로 ėļí•ī thisëĨž ė˜ˆėļĄí•˜ęļ° ė–īë ĩęēŒ 만ë“Īęļ°ë„ 한ë‹Ī.
반ëĐī, bind ëДė„œë“œė— ė˜í•ī 반환된 í•Ļėˆ˜ė˜ name 프로퍾티ė—ëŠ” 'bound'띾는 ė ‘두ė–ī가 ëķ™ė–ī callėī나 apply ëДė„œë“œëĨž ė‚ŽėšĐ하는 ęēƒëģīë‹Ī ė―”ë“œëĨž ėķ”ė í•˜ęļ°ę°€ ė‰―ë‹Ī는 ėžĨė ėī ėžˆë‹Ī.

ðŸ’Ą ėƒėœ„ ėŧĻ텍ėŠĪíŠļė˜ thisëĨž ë‚īëķ€ í•Ļėˆ˜ë‚˜ ė―œë°ą í•Ļėˆ˜ė— ė „닎하ęļ°

  • ëДė„œë“œė˜ ë‚īëķ€ í•Ļėˆ˜
var obj = {
  outer: function () {
    console.log(this); // obj
    var innerFunc = function () {
      console.log(this); // ė›ëž˜ëŠ” windowė§€ë§Œ call ëДė„œë“œė— ė˜í•ī obj가 ëĻ
    };
    innerFunc.call(this);
  }
};
obj.outer();
var obj = {
  outer: function () {
    console.log(this); // obj
    var innerFunc = function () {
      console.log(this); // ė›ëž˜ëŠ” windowė§€ë§Œ bind ëДė„œë“œė— ė˜í•ī obj가 ëĻ
    }.bind(this);
    innerFunc();
  },
};
obj.outer();
  • ė―œë°ą í•Ļėˆ˜ ðŸ”Ĩ
var obj = {
  logThis: function () {
    console.log(this);
  },
  logThisLater1: function () {
    // console.log(this); // ė—Žęļ°ė„œ this는 obj ( âˆĩ obj.logThisLater1(); )
    setTimeout(this.logThis, 500); // 따띾ė„œ, ė—Žęļ°ė„œ this도 obj
  },
  logThisLater2: function () {
    setTimeout(this.logThis.bind(this), 1000); // ė—Žęļ°ė„œ this도 obj
    // ❗ ė―œë°ą í•Ļėˆ˜ëĄœ 객ėēīė˜ ëДė„œë“œëĨž ė „닎했더띞도 ė―œë°ą í•Ļėˆ˜ 또한 í•Ļėˆ˜ėīęļ° 때ëŽļė—
    // thisëĨž 따로 바ėļë”Đí•īėĢžė§€ ė•ŠėœžëĐī 'ė―œë°ą í•Ļėˆ˜ ë‚īëķ€ė—ė„œė˜ this'는 ė›ëž˜ ė „ė—­ 객ėēīëĨž 가ëĶŽí‚Ļë‹Ī.
    // bind ëДė„œë“œëĨž ėīėšĐí•ī objëĨž ė―œë°ą í•Ļėˆ˜ ë‚īëķ€ė—ė„œė˜ this로 바ėļë”Đí•īėĪŽë‹Ī.
    // ėĢžė˜! this.logThisė—ė„œė˜ this는 objėīë‹Ī. ę·ļ럮나 ėī는 ė―œë°ą í•Ļėˆ˜ ë‚īëķ€ė—ė„œė˜ thisė—ëŠ” ė˜í–Ĩė„ ëŊļėđ˜ė§€ ė•ŠëŠ”ë‹Ī.
    // bind(this)ëĨž í†ĩí•ī ė―œë°ą í•Ļėˆ˜ ë‚īëķ€ė—ė„œė˜ this가 obj가 되는 ęēƒėīë‹Ī.
  }
};
obj.logThisLater1(); // window
obj.logThisLater2(); // ė›ëž˜ëŠ” windowė§€ë§Œ bind ëДė„œë“œė— ė˜í•ī obj가 ëĻ

(5) ëģ„도ė˜ ėļėžëĄœ thisëĨž 받는 ęē―ėš° (ė―œë°ą í•Ļėˆ˜ ë‚īė—ė„œė˜ this)

ėš”ė†ŒëĨž ėˆœíšŒí•˜ëĐīė„œ ė―œë°ą í•Ļėˆ˜ëĨž 반ëģĩ í˜ļėķœí•˜ëŠ” ë‚īėšĐė˜ ėžëķ€ ëДė„œë“œëŠ”, ëģ„도ė˜ ėļėžëĄœ thisëĨž 받ęļ°ë„ 한ë‹Ī.
ė―œë°ą í•Ļėˆ˜ė™€ í•Ļęŧ˜ this로 ė§€ė •í•  객ėēī(thisArg)ëĨž ėļėžëĄœ í•Ļęŧ˜ 받는 ęēƒėīë‹Ī.

var report = {
  sum: 0,
  count: 0,
  add: function () {
    // console.log(this); // 1. ė—Žęļ°ė„œ this는 report ( âˆĩ report.add(60, 85, 95); )
    var args = Array.prototype.slice.call(arguments);
    args.forEach(function (entry) {
      this.sum += entry; // 3. ė›ëž˜ ė―œë°ą í•Ļėˆ˜ë„ í•Ļėˆ˜ėīëŊ€ëĄœ ė―œë°ą í•Ļėˆ˜ ë‚īëķ€ė˜ this는 windowė§€ë§Œ, '2'ė— ė˜í•ī report가 ëĻ
      ++this.count;
    }, this); // 2. 따띾ė„œ, ė—Žęļ°ė„œ this도 report
  },
  average: function () {
    return this.sum / this.count; // ė—Žęļ° this는 '1'ęģž 같ė€ ë§Ĩë―ė—ė„œ report
  }
};

report.add(60, 85, 95);
console.log(report.sum, report.count, report.average()); // 240 3 80

âœĻ ë‚īėž 할 ęēƒ

  1. ė―œë°ą í•Ļėˆ˜
profile
ëŠĨ동ė ėœžëĄœ ė‚īėž, 행ëģĩ하ęēŒðŸ˜

0개ė˜ 댓ęļ€