๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Lect & Tip/javascript, jQuery

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฐ”์ธ๋”ฉ: ํ™œ์šฉ๊ณผ ์ฃผ์˜์ 

by ๋‚ฏ์„ ๊ณต๊ฐ„2019 2023. 11. 7.

๋ชฉ์ฐจ

    ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฐ”์ธ๋”ฉ: ํ™œ์šฉ๊ณผ ์ฃผ์˜์ 

    ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ๋ฐ”์ธ๋”ฉ(binding)์ด๋ž€, ํŠน์ • ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ๋‚˜ ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉ๋˜๋Š” this์˜ ๊ฐ’์„ ๊ณ ์ •ํ•˜๋Š” ๊ฒƒ์„ ๋งํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” this๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฐ์ฒด๊ฐ€ ์‹คํ–‰ ์ปจํ…์ŠคํŠธ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง€๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ํŠน์„ฑ ๋•Œ๋ฌธ์— ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. this์˜ ๋™์ ์ธ ํŠน์„ฑ์€ ์œ ์šฉํ•  ๋•Œ๋„ ์žˆ์ง€๋งŒ, ์˜ˆ๊ธฐ์น˜ ์•Š์€ ๋ฌธ์ œ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๊ธฐ์— ๋ฐ”์ธ๋”ฉ์„ ํ†ตํ•ด ์•ˆ์ •์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ํ•„์š”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

    ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฐ”์ธ๋”ฉ์˜ ํ•„์š”์„ฑ

    ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ํ•จ์ˆ˜๋Š” ํ˜ธ์ถœ๋˜๋Š” ๋ฐฉ์‹์— ๋”ฐ๋ผ this ๊ฐ’์ด ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋ฉ”์„œ๋“œ๋กœ ํ˜ธ์ถœ๋  ๋•Œ๋Š” this๊ฐ€ ๊ทธ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ค์ง€๋งŒ, ์ผ๋ฐ˜ ํ•จ์ˆ˜๋กœ ํ˜ธ์ถœ๋  ๋•Œ๋Š” this๊ฐ€ ์ „์—ญ ๊ฐ์ฒด(๋ธŒ๋ผ์šฐ์ €์—์„œ๋Š” window, Node.js์—์„œ๋Š” global)๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ฑฐ๋‚˜ undefined(์—„๊ฒฉ ๋ชจ๋“œ์—์„œ)๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    ์ด๋Ÿฐ ํŠน์„ฑ ๋•Œ๋ฌธ์—, ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋‚˜ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๊ฐ™์€ ๊ณณ์—์„œ ์›ํ•˜์ง€ ์•Š๋Š” this ๋ฐ”์ธ๋”ฉ์ด ๋ฐœ์ƒํ•˜๊ณค ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์ฝœ๋ฐฑ์œผ๋กœ ์ „๋‹ฌํ•  ๋•Œ ์ข…์ข… ๋ฐœ์ƒํ•˜๋Š”๋ฐ, ์ด๋•Œ ๋ฐ”์ธ๋”ฉ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด this๊ฐ€ ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๊ฐ’์„ ๊ฐ€๋ฆฌํ‚ค๊ฒŒ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฐ”์ธ๋”ฉ ๋ฐฉ๋ฒ•๋“ค

    1. Function.prototype.bind()
      bind() ๋ฉ”์„œ๋“œ๋Š” this๋ฅผ ํŠน์ • ๊ฐ’์— ๊ณ ์ •์‹œํ‚ค๋Š” ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์€ this๊ฐ€ ๋™์ ์œผ๋กœ ๋ณ€ํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ณ , ํ•ญ์ƒ ์ง€์ •ํ•œ ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    2. ํ™”์‚ดํ‘œ ํ•จ์ˆ˜
      ES6๋ถ€ํ„ฐ ์ถ”๊ฐ€๋œ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” this๋ฅผ ๋ฐ”์ธ๋”ฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋Œ€์‹ , ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๊ฐ€ ์„ ์–ธ๋œ ์‹œ์ ์˜ this ๊ฐ’์„ "์–ดํœ˜์ ์œผ๋กœ" ๋ฐ”์ธ๋”ฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์ฃผ๋กœ ํด๋ž˜์Šค์˜ ๋ฉ”์„œ๋“œ์—์„œ ์ฝœ๋ฐฑ์„ ๋‹ค๋ฃฐ ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.
    3. ํด๋กœ์ €๋ฅผ ํ™œ์šฉํ•œ ๋ฐ”์ธ๋”ฉ
      ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜(๋˜๋Š” ํด๋กœ์ €)๋ฅผ ์ด์šฉํ•˜์—ฌ this๋ฅผ ์›ํ•˜๋Š” ๊ฐ’์— ๊ณ ์ •ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์€ bind()๋‚˜ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” ์ƒํ™ฉ์—์„œ ์œ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    ์ฃผ์˜์ 

    • bind() ๋ฉ”์„œ๋“œ๋Š” ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์„ฑ๋Šฅ์— ๋ฏผ๊ฐํ•œ ์ƒํ™ฉ์—์„œ๋Š” ๊ณผ๋„ํ•œ ์‚ฌ์šฉ์„ ํ”ผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    • ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” this ์™ธ์—๋„ arguments, super, new.target์„ ๋ฐ”์ธ๋”ฉํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, ์ด๋ฅผ ํ•„์š”๋กœ ํ•˜๋Š” ์ƒํ™ฉ์—์„œ๋Š” ์ ํ•ฉํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ํด๋กœ์ €๋ฅผ ์ด์šฉํ•œ ๋ฐ”์ธ๋”ฉ์€ ์ฝ”๋“œ์˜ ๋ณต์žก์„ฑ์„ ์ฆ๊ฐ€์‹œํ‚ฌ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ๋ช…ํ™•ํ•œ ์ดํ•ด ์—†์ด ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์–ด๋ ค์›Œ์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฐ”์ธ๋”ฉ ์‹ค์ œ ํ™œ์šฉ ์‚ฌ๋ก€

    ์ฝ”๋“œ ์˜ˆ์ œ๋ฅผ ํ†ตํ•ด ๋ฐ”์ธ๋”ฉ์˜ ํ™œ์šฉ ์‚ฌ๋ก€๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

    1. bind() ํ™œ์šฉ ์˜ˆ์ œ์œ„ ์ฝ”๋“œ์—์„œ setTimeout ๋‚ด๋ถ€์—์„œ person.greet๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ this๋ฅผ person ๊ฐ์ฒด์— ๊ณ ์ •์‹œํ‚ค๊ธฐ ์œ„ํ•ด bind()๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.
    2. const person = { name: 'ํ™๊ธธ๋™', greet: function() { console.log(`์•ˆ๋…•ํ•˜์„ธ์š”, ${this.name}์ž…๋‹ˆ๋‹ค.`); } }; setTimeout(person.greet.bind(person), 1000);
    3. ํ™”์‚ดํ‘œ ํ•จ์ˆ˜ ํ™œ์šฉ ์˜ˆ์ œํด๋ž˜์Šค์˜ greet ๋ฉ”์„œ๋“œ๋ฅผ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋กœ ์„ ์–ธํ•จ์œผ๋กœ์จ, ์–ด๋””์„œ๋“  this.name์ด person ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.
    4. class Person { constructor(name) { this.name = name; } greet = () => { console.log(`์•ˆ๋…•ํ•˜์„ธ์š”, ${this.name}์ž…๋‹ˆ๋‹ค.`); } } const person = new Person('ํ™๊ธธ๋™'); setTimeout(person.greet, 1000);
    5. ํด๋กœ์ € ํ™œ์šฉ ์˜ˆ์ œmakeGreet ํ•จ์ˆ˜๋Š” ํด๋กœ์ €๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ , ์ด ํด๋กœ์ €๋Š” name ๋ณ€์ˆ˜๋ฅผ ๊ธฐ์–ตํ•ฉ๋‹ˆ๋‹ค. setTimeout์—์„œ ์‚ฌ์šฉ๋˜๋Š” greet ํ•จ์ˆ˜๋Š” this์— ์˜์กดํ•˜์ง€ ์•Š๊ณ  ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.
    6. function makeGreet(name) { return function() { console.log(`์•ˆ๋…•ํ•˜์„ธ์š”, ${name}์ž…๋‹ˆ๋‹ค.`); } } const greet = makeGreet('ํ™๊ธธ๋™'); setTimeout(greet, 1000);

    ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ this ๋ฐ”์ธ๋”ฉ์€ ๋•Œ๋กœ ๋ณต์žกํ•˜๊ณ  ํ˜ผ๋ž€์Šค๋Ÿฌ์šธ ์ˆ˜ ์žˆ์ง€๋งŒ, ๋ฐ”์ธ๋”ฉ์˜ ๊ฐœ๋…๊ณผ ๋ฐฉ๋ฒ•์„ ์ดํ•ดํ•˜๊ณ  ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ํ™œ์šฉํ•œ๋‹ค๋ฉด ๋”์šฑ ๊ฒฌ๊ณ ํ•˜๊ณ  ์•ˆ์ •์ ์ธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•ญ์ƒ ๋ฐ”์ธ๋”ฉ์˜ ๋ชฉ์ ๊ณผ ์ƒํ™ฉ์„ ๊ณ ๋ คํ•˜์—ฌ ์ ์ ˆํ•œ ๋ฐฉ๋ฒ•์„ ์„ ํƒํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

    ํ‚ค์›Œ๋“œ: ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฐ”์ธ๋”ฉ, this, bind() ๋ฉ”์„œ๋“œ, ํ™”์‚ดํ‘œ ํ•จ์ˆ˜, ํด๋กœ์ €, ์ฝœ๋ฐฑ ํ•จ์ˆ˜, ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ, ์‹คํ–‰ ์ปจํ…์ŠคํŠธ, ์–ดํœ˜์  ๋ฐ”์ธ๋”ฉ, ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ, ES6

    ๋ฐ˜์‘ํ˜•

    ๋Œ“๊ธ€