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 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๋ ํธ์ถํ ํจ์์ ์ธ์๋ฅผ ์ ๋ฌํ๋ ๋ฐฉ์๋ง ๋ค๋ฅผ ๋ฟ ๋์ผํ๊ฒ ๋์ํ๋ค.
testfun.call(obj,1,2)
testfun.apply(obj,[1,2]
)
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 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์ ํด์ค์ผํ๋ค.