๐ŸคFunction.prototype.apply/call/bind

๊น€์ฒ ์ค€ยท2022๋…„ 2์›” 22์ผ
0

Javascript

๋ชฉ๋ก ๋ณด๊ธฐ
7/16

Function.prototype.apply

Function.prototype.call(thisArg,[arguments])
this binding์„ ๋ณ€๊ฒฝํ•˜์—ฌ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ ์œ„ํ•œ ๋ฉ”์„œ๋“œ

function testfun(a,b){
	return this
}

testfun() // this => Window

const obj = {x:1}

testfun.apply(obj) //  this => {obj}

testfun.apply() // this => Window

์ผ๋ฐ˜ ํ•จ์ˆ˜๋‚ด์—์„œ this๋Š” window๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฅดํ‚จ๋‹ค.

  • ๋ณธ์งˆ์ ์ธ ๊ธฐ๋Šฅ : ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ

  • ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด์„œ ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•œ ํŠน์ • ๊ฐ์ฒด๋ฅผ ํ˜ธ์ถœํ•œ ํ•จ์ˆ˜์˜ this์— bindingํ•œ๋‹ค.

  • ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋ฅผ ์ „๋‹ฌํ•˜์ง€ ์•Š๊ณ  apply๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ธฐ์กด๊ณผ ๊ฐ™์ด this๊ฐ€ window์— binding๋œ๋‹ค.

  • apply ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ ์ธ์ž๋ฅผ ์ „๋‹ฌํ•˜๊ณ  ์‹ถ์„ ๋•Œ์—๋Š” apply์˜ ๋‘๋ฒˆ์งธ ์ธ์ž์— ๋ฐฐ์—ด๋กœ ๋ฌถ์–ด ์ „๋‹ฌํ•ด์ค€๋‹ค.
    testfun(obj,[1,2])

Function.prototype.call

function testfun(a,b){
	return this
}

testfun() // this => Window

const obj = {x:1}

testfun.call(obj) //  this => {obj}

testfun.call() // this => Window
  • ๋ณธ์งˆ์ ์ธ ๊ธฐ๋Šฅ : ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ

  • ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด์„œ ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•œ ํŠน์ • ๊ฐ์ฒด๋ฅผ ํ˜ธ์ถœํ•œ ํ•จ์ˆ˜์˜ this์— bindingํ•œ๋‹ค.

  • call ๋ฉ”์„œ๋“œ๋Š” ํ˜ธ์ถœํ•  ํ•จ์ˆ˜์˜ ์ธ์ˆ˜๋ฅผ ์‰ผํ‘œ๋กœ ๊ตฌ๋ถ„ํ•œ ๋ฆฌ์ŠคํŠธ ํ˜•์‹์œผ๋กœ ์ „๋‹ฌํ•œ๋‹ค.
    testfun.call(obj,1,2)

call๊ณผ apply์˜ ์ฐจ์ด

call๊ณผ apply๋Š” ํ˜ธ์ถœํ•  ํ•จ์ˆ˜์— ์ธ์ˆ˜๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ์‹๋งŒ ๋‹ค๋ฅผ ๋ฟ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•œ๋‹ค.

testfun.call(obj,1,2)

testfun.apply(obj,[1,2]
)

call,apply์˜ ํ™œ์šฉ

apply์™€ call ๋ฉ”์„œ๋“œ๋Š” Array.prototype.slice๋ฉ”์„œ๋“œ์™€ ํ•จ๊ป˜ arguments์™€ ๊ฐ™์€ ์œ ์‚ฌ ๋ฐฐ์—ด ๊ฐ์ฒด๋ฅผ ๋ฐฐ์—ดํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.

Array.prototype.slice๋Š” ์ธ์ˆ˜๋กœ ํ• ๋‹นํ•œ ๋ฐฐ์—ด์„ ๋ณต์‚ฌํ•ด์ฃผ๋Š” ๋ฉ”์„œ๋“œ์ด๋‹ค.

const arr = [1,2,3]
const copyarr = arr.slice()

Array.prototype.slice์— call/apply๋ฅผ ์ ์šฉํ•˜์—ฌ arguments๋ฅผ ํ• ๋‹นํ•˜๋ฉด ๊ฐ’์„ ์ €์žฅํ•˜๋ฉด ํ•ด๋‹น ๊ฐ’์€ arguments๊ฐ€ ๋ฐฐ์—ดํ™”๋œ ๊ฐ’์ด ๋œ๋‹ค.

funtion testfun(a,b){
  
console.log(arguments)

}

testfun(1,2) // {0:1,1:2}




function arrayedTestfun(a,b) {

  const callarr = Array.prototype.slice.call(arguments)
  
  const applyarr = Array.prototype.slice.apply(arguments)

  console.log(callarr)
  console.log(applyarr)

}

arrayedTestfun(1,2) // [1,2] [1,2]

Array.prototype.slice()๋ผ๋Š” ๋ฉ”์„œ๋“œ์•ˆ์—์„œ this๋Š” Array๋ฅผ ๊ฐ€๋ฅดํ‚จ๋‹ค.
๋•Œ๋ฌธ์— Array.prototype.slice()์„ ํ˜ธ์ถœํ•˜๋ฉด ๋นˆ ๋ฐฐ์—ด๊ฐ’์„ ๊ฐ€์ง€๊ฒŒ ๋œ๋‹ค.
const arr = Array.prototype.slice() //[]

ํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์„œ ๋‹ค๋ฅธ ๊ฐ์ฒด๋ฅผ call/apply๋ฅผ ํ†ตํ•ด this binding์„ ํ•ด์ฃผ๋ฉด ํ•ด๋‹น ๊ฐ์ฒด๊ฐ€ this๊ฐ€ ๋˜์–ด slice์„ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.

Function.prototype.bind

function bindingFun() {
  console.log(this);
}

const obj = { x: 1 };

// call/apply์™€ ๋‹ฌ๋ฆฌ ํ˜ธ์ถœ์„ ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ํ˜ธ์ถœํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ช…์‹œ์ ์œผ๋กœ ํ˜ธ์ถœํ•ด์ค˜์•ผํ•จ.
bindingFun.bind(obj)();

bind๋ฉ”์„œ๋“œ๋Š” apply์™€ call ๋ฉ”์„œ๋“œ์™€ ๋‹ฌ๋ฆฌ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ  this๋กœ ์‚ฌ์šฉํ•  ๊ฐ์ฒด๋งŒ ์ „๋‹ฌํ•œ๋‹ค.

์ฆ‰, bind ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด this binding์„ ํ•ด์ค€ ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
bindingFun = bindingFun.bind(obj) => this์— obj๋ฅผ bindํ•œ ํ•จ์ˆ˜

bind ๋ฉ”์„œ๋“œ๋Š” ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์ง€๋Š” ์•Š์œผ๋ฏ€๋กœ ๋ช…์‹œ์ ์œผ๋กœ ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค.

no bind

const person = {
  name: "Lee",
  foo(callback) {
    setTimeout(callback, 3000);
  },
};

person.foo(function () {
  console.log(`Hello, my name is ${this.name}`);
}); // Hello, my name is

bind

const person = {
  name: "Lee",
  foo(callback) {
    setTimeout(callback.bind(this), 3000);
  },
};

person.foo(function () {
  console.log(`Hello, my name is ${this.name}`);
});	//Hello, my name is Lee.

์œ„ ์˜ˆ์ œ์—์„œ binding์„ ํ•˜์ง€ ์•Š์€ person์˜ ๋ฉ”์„œ๋“œ foo๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด this๊ฐ€ window์ด๋‹ค.

๋•Œ๋ฌธ์— person ๊ฐ์ฒด๋ฅผ ๋ฐ”์ธ๋”ฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์ฝœ๋ฐฑํ•จ์ˆ˜์—์„œ this binding์„ ํ•ด์ค˜์•ผํ•œ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€