다른 언어와 달리 JavaScript에서는 함수도 객체이다. 이 때문에 메소드가 아닌 함수 내부에서도 this
를 사용할 수 있다. 하지만 JS의 this
는 고정적이지 않고 경우에 따라 다르다.(여기를 참고) 이런 특성은 개발 시에 개발자가 의도하지 않은 this
가 적용됨으로 문제가 될 수 있다. 이를 개발자가 제어할 수 있도록 한 개념이 this의 binding이다.
추가적으로 자바스크립트의 함수는 호출될 때, 매개변수로 전달되는 인자값 이외에,
arguments 객체
와this
를 암묵적으로 전달 받는 점을 알아두자.function sum(num1, num2) { console.log(arguments); // [Arguments] { '0': 10, '1': 20 } console.log(this); // window or global return num1 + num2; } sum(10, 20);
JS의 함수 객체는 call()
, apply()
, bind()
라는 this의 binding을 위해 내장된 기본 메소드들을 가지고 있다. 이 메소드들은 함수 내부에서 this
를 자유롭게 사용하기 위해서 존재한다.
call()은 주어진 this
값과 인자들을 매개변수로 받아서 함수를 실행하는 메소드이다.
let Leo = {
name: "Leo",
math_score: 80,
coding_score: 95,
};
let Neo = {
name: "Neo",
math_score: 80,
coding_score: 60,
};
function sum(arrow) {
return arrow + (this.math_score + this.coding_score);
}
console.log(sum.call(Leo, "--> ")); // --> 175
console.log(sum.call(Neo, "==> ")); // ==> 140
위의 예시와 같이 함수의 this
를 Leo
나 Neo
와 같이 원하는 객체로 지정해 줄 수 있다.
apply()는 주어진 this
값과 배열을 매개변수로 받아서 함수를 실행하는 메소드이다.
const array = [1, 2, 3];
const elements = [10, 20, 30];
array.push.apply(array, elements);
console.log(array); // [ 1, 2, 3, 10, 20, 30 ]
call과 apply의 차이점
둘 다 첫 번째 인자로는this
를 동일하게 받는다. 하지만 두 번째 인자를 받는 방식이 다르다.call()
의 경우에는 기본 자료형의 변수들을 인자로 받는 반면에apply()
는 배열을 인자로 받는다.
bind()는 해당 함수의 this
를 고정한 함수를 반환한다. 구체적으로는 함수 객체를 감싼(wrap) 새로운 bound 함수를 만들어서 this
를 세팅하고 이 bound 함수를 반환한다.
let Leo = {
name: "Leo",
math_score: 80,
coding_score: 95,
};
function sum() {
return this.math_score + this.coding_score;
}
let newSum = sum.bind(Leo);
console.log(newSum());