Lexical this๋Š” ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๊ฐ€ ์ž์‹ ๋งŒ์˜ this๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ , ์ž์‹ ์„ ๊ฐ์‹ธ๋Š” ์™ธ๋ถ€ ์Šค์ฝ”ํ”„์˜ this๋ฅผ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

์ผ๋ฐ˜ ํ•จ์ˆ˜ vs ํ™”์‚ดํ‘œ ํ•จ์ˆ˜

์ผ๋ฐ˜ ํ•จ์ˆ˜์˜ this

  • ํ˜ธ์ถœ ๋ฐฉ์‹์— ๋”ฐ๋ผ this๊ฐ€ ๋™์ ์œผ๋กœ ๊ฒฐ์ •๋จ
  • ํ•จ์ˆ˜๊ฐ€ ์–ด๋–ป๊ฒŒ ํ˜ธ์ถœ๋˜์—ˆ๋Š”์ง€๊ฐ€ ์ค‘์š”
const user = {
    name: "John",
    greet: function() {
        console.log(`Hello, ${this.name}`);
    }
};
 
user.greet(); // "Hello, John"
const greet = user.greet;
greet(); // "Hello, undefined" (this๊ฐ€ ์ „์—ญ ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ด)

ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์˜ this (Lexical this)

  • ํ•จ์ˆ˜๊ฐ€ ์„ ์–ธ๋œ ์œ„์น˜์˜ this๋ฅผ ์‚ฌ์šฉ
  • ํ˜ธ์ถœ ๋ฐฉ์‹๊ณผ ๊ด€๊ณ„์—†์ด this๊ฐ€ ๊ณ ์ •๋จ
const user = {
    name: "John",
    greet: () => {
        console.log(`Hello, ${this.name}`);
    }
};
 
user.greet(); // this๋Š” user๊ฐ€ ์•„๋‹Œ ์™ธ๋ถ€ ์Šค์ฝ”ํ”„์˜ this๋ฅผ ๊ฐ€๋ฆฌํ‚ด

์‹ค์ œ ํ™œ์šฉ ์‚ฌ๋ก€

ํด๋ž˜์Šค ๋ฉ”์„œ๋“œ์—์„œ์˜ ์ฝœ๋ฐฑ

// ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ์ฝ”๋“œ
class Counter {
    constructor() {
        this.count = 0;
    }
    
    start() {
        setInterval(function() {
            // this๊ฐ€ ์ „์—ญ ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌ์ผœ์„œ ์˜๋„ํ•œ ๋Œ€๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š์Œ
            this.count++;
            console.log(this.count);
        }, 1000);
    }
}
 
// ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋กœ ํ•ด๊ฒฐ
class Counter {
    constructor() {
        this.count = 0;
    }
    
    start() {
        setInterval(() => {
            // this๊ฐ€ Counter ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€๋ฆฌํ‚ด
            this.count++;
            console.log(this.count);
        }, 1000);
    }
}

์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ

// ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ์ฝ”๋“œ
class App {
    constructor() {
        this.buttonClicks = 0;
        this.button = document.querySelector('button');
        
        this.button.addEventListener('click', function() {
            // this๊ฐ€ ๋ฒ„ํŠผ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๊ฐ€๋ฆฌํ‚ด
            this.buttonClicks++; // ์—๋Ÿฌ!
        });
    }
}
 
// ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋กœ ํ•ด๊ฒฐ
class App {
    constructor() {
        this.buttonClicks = 0;
        this.button = document.querySelector('button');
        
        this.button.addEventListener('click', () => {
            // this๊ฐ€ App ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€๋ฆฌํ‚ด
            this.buttonClicks++;
        });
    }
}

Lexical this๊ฐ€ ์œ ์šฉํ•œ ์ƒํ™ฉ

  1. ๋น„๋™๊ธฐ ์ฝœ๋ฐฑ
class DataFetcher {
    constructor() {
        this.data = null;
    }
    
    fetch() {
        setTimeout(() => {
            // this๊ฐ€ DataFetcher ์ธ์Šคํ„ด์Šค๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ฐ€๋ฆฌํ‚ด
            this.data = "fetched data";
            console.log(this.data);
        }, 1000);
    }
}
  1. ๋ฉ”์„œ๋“œ ์ฒด์ด๋‹
class Builder {
    constructor() {
        this.items = [];
    }
    
    addItem(item) {
        // ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋กœ ์ธํ•ด this๊ฐ€ Builder ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€๋ฆฌํ‚ด
        process.nextTick(() => {
            this.items.push(item);
            console.log(this.items);
        });
        return this;
    }
}

์ฃผ์˜์‚ฌํ•ญ

  1. ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ๋กœ ๋ถ€์ ์ ˆํ•œ ๊ฒฝ์šฐ
// ์ž˜๋ชป๋œ ์‚ฌ์šฉ
const obj = {
    name: "John",
    greet: () => {
        console.log(`Hello, ${this.name}`);
    }
};
 
// ์˜ฌ๋ฐ”๋ฅธ ์‚ฌ์šฉ
const obj = {
    name: "John",
    greet() {
        console.log(`Hello, ${this.name}`);
    }
};

๊ฐ์ฒด ๋ฉ”์„œ๋“œ์—์„œ ์ผ๋ฐ˜ ํ•จ์ˆ˜์™€ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์˜ ์ฐจ์ด

  1. ํ”„๋กœํ† ํƒ€์ž… ๋ฉ”์„œ๋“œ๋กœ ๋ถ€์ ์ ˆํ•œ ๊ฒฝ์šฐ
// ํ”ผํ•ด์•ผ ํ•  ์‚ฌ์šฉ
Function.prototype.myBind = () => {
    console.log(this); // ์ž˜๋ชป๋œ this ๋ฐ”์ธ๋”ฉ
};
 
// ์˜ฌ๋ฐ”๋ฅธ ์‚ฌ์šฉ
Function.prototype.myBind = function() {
    console.log(this); // ์ •์ƒ์ ์ธ this ๋ฐ”์ธ๋”ฉ
};

์ •๋ฆฌ

  1. Lexical this์˜ ํ•ต์‹ฌ

    • ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” ์ž์‹ ์˜ this๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š์Œ
    • ์„ ์–ธ๋œ ์œ„์น˜์˜ this๋ฅผ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉ
    • ํ˜ธ์ถœ ๋ฐฉ์‹์— ๊ด€๊ณ„์—†์ด this๊ฐ€ ์œ ์ง€๋จ
  2. ์‚ฌ์šฉํ•˜๋ฉด ์ข‹์€ ๊ฒฝ์šฐ

    • ์ฝœ๋ฐฑ ํ•จ์ˆ˜
    • ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ
    • ๋น„๋™๊ธฐ ํ•จ์ˆ˜
    • ์ค‘์ฒฉ ํ•จ์ˆ˜
  3. ํ”ผํ•ด์•ผ ํ•  ๊ฒฝ์šฐ

    • ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ
    • ํ”„๋กœํ† ํƒ€์ž… ๋ฉ”์„œ๋“œ
    • this๋ฅผ ๋™์ ์œผ๋กœ ๋ฐ”์ธ๋”ฉํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ