๊ด€๋ฆฌ ๋ฉ”๋‰ด

Bin's Blog

call, apply, bind ๋ฉ”์„œ๋“œ ๋ณธ๋ฌธ

JavaScript

call, apply, bind ๋ฉ”์„œ๋“œ

hotIce 2023. 5. 24. 12:02
728x90

๐Ÿง ๋ช…์‹œ์ ์œผ๋กœ this๋ฅผ ๋ฐ”์ธ๋”ฉํ•˜๋Š” ๋ฐฉ๋ฒ•์˜ ํฌ๊ฒŒ ์„ธ ๊ฐ€์ง€๋ฅผ ์˜ค๋Š˜ ์‚ดํŽด๋ณด๋ ค๊ณ  ํ•œ๋‹ค.

๋ฐ”์ธ๋”ฉ์€ ๋ญ˜๊นŒ? ์‰ฝ๊ฒŒ ๋งํ•ด์„œ ๋ฌถ๋Š”๋‹ค๋Š” ๋œป์ด๋‹ค. ํŠน์ •ํ•œ ์ด๋ฆ„์ด๋‚˜ ๊ฐ’์ด๋‚˜ ๊ธฐ๋Šฅ์„ ๋ฌถ์–ด์„œ ์‚ฌ์šฉํ•˜๊ฒ ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค. ์–ด๋–ค ํ‚ค๋ณด๋“œ์— A์— ํŠน์ •ํ•œ ๋™์ž‘์ธ ์ ํ”„๋ฅผ ๋ฌถ์–ด์„œ ํ”„๋กœ๊ทธ๋žจ์„ ๋งŒ๋“ค์—ˆ๋‹ค. ์ด์ œ Aํ‚ค๋ฅผ ๋ˆ„๋ฅด๋ฉด ์ ํ”„ํ•˜๋Š” ๋™์ž‘์ด ์‹คํ–‰๋œ๋‹ค. ๋‹จ์ถ•ํ‚ค๊ฐ€ ๋ฐ”์ธ๋”ฉ์ด๋‹ค.  

 

1๏ธโƒฃ call ๋ฉ”์„œ๋“œ 

- call ๋ฉ”์„œ๋“œ๋Š” ๋ฉ”์„œ๋“œ์˜ ํ˜ธ์ถœ ์ฃผ์ฒด์ธ ํ•จ์ˆ˜๋ฅผ ์ฆ‰์‹œ ์‹คํ–‰ํ•˜๋„๋ก ํ•˜๋Š” ๋ช…๋ น์ด๋‹ค. ์ด๋•Œ call ๋ฉ”์„œ๋“œ์˜ ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋ฅผ this๋กœ ๋ฐ”์ธ๋”ฉํ•˜๊ณ , ์ดํ›„์˜ ์ธ์ž๋“ค์„ ํ˜ธ์ถœํ•  ํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ํ•œ๋‹ค. 

 

- call ๋ฉ”์„œ๋“œ ์˜ˆ์‹œ

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

};

// 1, 2, 3
obj.method(2, 3);

// 4, 5, 6
obj.method.call({ a: 4}, 5, 6)

 

์œ„์—์„œ ๋ดค๋“ฏ์ด call์˜ ์ฒซ ๋ฒˆ์งธ ์ธ์ž๊ฐ€ this๋กœ ๋ฐ”์ธ๋”ฉ์ด ๋˜์–ด์„œ ์ด์ „์—๋Š” a๊ฐ€ 1์„ ๊ฐ€๋ฆฌ์ผฐ๋Š”๋ฐ ์ด์ œ๋Š” this๊ฐ€ call์˜ ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋‹ˆ๊นŒ a๋Š” 4๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ฒŒ ๋œ๋‹ค.

 

2๏ธโƒฃ apply ๋ฉ”์„œ๋“œ 

 - apply ๋ฉ”์„œ๋“œ๋„ call ๋ฉ”์„œ๋“œ์™€ ๋น„์Šทํ•œ๋ฐ ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค๋ฉด ๋‘ ๋ฒˆ์งธ ์ธ์ž๋ฅผ ๋ฐฐ์—ด๋กœ ๋ฐ›์•„ ๊ทธ ๋ฐฐ์—ด์˜ ์š”์†Œ๋“ค์„ ํ˜ธ์ถœํ•  ํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ง€์ •ํ•œ๋‹ค. 

 

- apply ๋ฉ”์„œ๋“œ ์˜ˆ์‹œ

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

};

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

 

3๏ธโƒฃ bind ๋ฉ”์„œ๋“œ

 - bind ๋ฉ”์„œ๋“œ๋Š” ES5์—์„œ ์ถ”๊ฐ€๋œ ๊ธฐ๋Šฅ์œผ๋กœ, call๊ณผ ๋น„์Šทํ•˜์ง€๋งŒ ์ฆ‰์‹œ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ  ๋„˜๊ฒจ ๋ฐ›์€ this ๋ฐ ์ธ์ˆ˜๋“ค์„ ๋ฐ”ํƒ•์œผ๋กœ ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ธฐ๋งŒ ํ•˜๋Š” ๋ฉ”์„œ๋“œ์ด๋‹ค. 

- bind ๋ฉ”์„œ๋“œ๋Š” ํ•จ์ˆ˜์— this๋ฅผ ๋ฏธ๋ฆฌ ์ ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ๋ถ€๋ถ„ ์ ์šฉ ํ•จ์ˆ˜๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ๋ชฉ์ ์„ ๋ชจ๋‘ ์ง€๋‹Œ๋‹ค. 

 

- bind ๋ฉ”์„œ๋“œ ์˜ˆ์‹œ

let func = function(a, b, c, d) {
    console.log(this, a, b, c, d);

};

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


let bindFunc1 = func.bind({ x: 1});

// { x:1 } 5 6 7 8
bindFunc1(5, 6, 7, 8);

let bindFunc2 = func.bind({ x: 1}, 4, 5);

// { x: 1} 4 5 6 7
bindFunc2(6, 7);

// { x: 1} 4 5 8 9
bindFunc2(8, 9);

- ๋ฐ”๋กœ ์œ„์— ๋‘ ์ค„์—์„œ 6, 7์„ ๋„˜๊ธด ๋ถ€๋ถ„์—์„œ ๋ณด๋ฉด this ๊ฐ’์ด ๋ฐ”๋€ ๊ฒƒ์„ ์ œ์™ธํ•˜๊ณ ๋Š” ์ตœ์ดˆ func ํ•จ์ˆ˜์— 4, 5, 6, 7์„ ๋„˜๊ธด ๊ฒƒ๊ณผ ๊ฐ™์€ ๋™์ž‘์„ ํ•œ๋‹ค. 

 

3๏ธโƒฃ-1. bind ๋ฉ”์„œ๋“œ

- bind ๋ฉ”์„œ๋“œ๋ฅผ ์ ์šฉํ•ด์„œ ์ƒˆ๋กœ ๋งŒ๋“  ํ•จ์ˆ˜๋Š” ํ•œ ๊ฐ€์ง€ ๋…ํŠนํ•œ ์„ฑ์งˆ์ด ์žˆ๋‹ค. ๋ฐ”๋กœ name ํ”„๋กœํผ๋‹ˆ ๋™์‚ฌ bind์˜ ์ˆ˜๋™ํƒœ์ธ bound ๊ฐ€ ์ ‘๋‘์–ด๋กœ ๋ถ™๋Š”๋‹ค.

- ์–ด๋–ค ํ•จ์ˆ˜์˜ name ํ”„๋กœํผํ‹ฐ๊ฐ€ "bound xxx"๋ผ๋ฉด ์ด๋Š” ๊ณง ํ•จ์ˆ˜๋ช…์ด xxx์ธ ์›๋ณธ ํ•จ์ˆ˜์— bind ๋ฉ”์„œ๋“œ๋ฅผ ์ ์šฉํ•œ ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋ผ๋Š” ์˜๋ฏธ๊ฐ€ ๋˜๋ฏ€๋กœ ๊ธฐ์กด์˜ call์ด๋‚˜ apply๋ณด๋‹ค ์ฝ”๋“œ๋ฅผ ์ถ”์ ํ•˜๊ธฐ์— ์ˆ˜์›”ํ•ด์ง„ ๋ฉด์ด ์žˆ๋‹ค.

let func = function (a, b, c, d) {
    console.log(this, a, b, c ,d);
};

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

Ex) bind ๋ฉ”์„œ๋“œ - ๋‚ด๋ถ€ํ•จ์ˆ˜์— this ์ „๋‹ฌ

let obj = {
    logThis: function() {
        console.log(this);
    },
    
    logThisLater1: function() {
       setTimeout(this.logThis, 500);
    },

    logThisLater2: function() {
       setTimeout(this.logThis.bind(this), 1000);
    },


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

 

4๏ธโƒฃ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์˜ ์˜ˆ์™ธ์‚ฌํ•ญ 

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

let obj = {
    outer: function () {
        console.log(this);
        let innerFunc = () =? {
            console.log(this);
       
        };
        innerFunc();
    
    }

};

obj.outer();

 

5๏ธโƒฃ ๋ณ„๋„์˜ ์ธ์ž๋กœ this๋ฅผ ๋ฐ›๋Š” ๊ฒฝ์šฐ(์ฝœ๋ฐฑ ํ•จ์ˆ˜ ๋‚ด์—์„œ์˜ this)

Ex) forEach ๋ฉ”์„œ๋“œ

let report = {
    sum: 0,
    count: 0,
    add: function() {
        let 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);
// 240 3 80
console.log(report.sum, report.count, report.average());

์ฝœ๋ฐฑ ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ์˜ this๋Š” add ๋ฉ”์„œ๋“œ์—์„œ์˜ this๊ฐ€ ์ „๋‹ฌ๋œ ์ƒํƒœ์ด๋ฏ€๋กœ add ๋ฉ”์„œ๋“œ์˜ this(report)๋ฅผ ๊ทธ๋Œ€๋กœ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ๋‹ค

 

6๏ธโƒฃ ์ฝœ๋ฐฑ ํ•จ์ˆ˜์™€ ํ•จ๊ป˜ 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])
728x90

'JavaScript' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

includes ๋ฉ”์„œ๋“œ  (0) 2023.05.26
some ๋ฉ”์„œ๋“œ  (0) 2023.05.25
Symbol  (0) 2023.05.19
Promise  (0) 2023.05.18
๋น„๋™๊ธฐ  (0) 2023.05.17