들어가기 앞서
자바스크립트에는 this 키워드가 있습니다.
이 this 키워드는 현재 실행 컨텍스트를 기준으로 누가 호출했는지를 나타냅니다.
const airplane = {
airline: 'korea',
data: 'S',
bookings: [],
book(flightNum, name) {
console.log(`${name} booked on ${this.airline} flight ${this.data} ${flightNum}`)
this.bookings.push({flight: `${this.data} ${flightNum}`,name})
}
}
위의 경우에 book 함수에서 this 키워드는 airplane 객체를 가리키게 될 것입니다.
또한 자바스크립트는 일급 함수 기능을 가지고 있기 때문에, 함수 자체가 값이 될 수 있습니다.
// first-class function
const book = airplane.book;
따라서 airplane 객체 내에 있는 book 함수를 따로 저장할 수 있습니다.
이제 위에서 선언한 book 함수를 사용해보려고 합니다.
book(23, 'action');

this.airline에 접근하려고 하자 undefined로 바뀌고 오류가 발생했습니다.
book 함수는 더이상 airplane 객체 내에 있는 메서드가 아닌 일반적인 함수가 되었기 때문에
this 키워드가 작동하지 않습니다.
call, apply, bind 메서드 사용
따라서 함수를 호출하는 다른 방법을 사용해야 하는데, 그것이 바로 위의 3가지 메서드 입니다.
call 메서드 사용
먼저 다른 비행기 객체를 하나 더 만들겠습니다.
const planeair = {
airline: 'kor',
data: 'M',
bookings: []
}
// call 메서드 사용
book.call(planeair, 23, 'action');
console.log(planeair)
위에서 선언한 book 함수에 call 메서드를 붙여서 사용하면, 첫 번째 매개변수로 우리가 사용할
객체를 지정할 수 있습니다.

오류없이 book 함수가 planeair 객체에 대해 작동한 것을 볼 수 있습니다.
apply 메서드 사용
apply 메서드는 call 메서드와 같은 일을 하지만,
첫 번째 매개변수 이후에 매개변수 대신 배열을 넣어야 한다는 차이점이 있습니다.
예를들어 비행기 객체를 하나 더 생성하고 사용해보겠습니다.
const yesplane = {
name: 'yes',
data: 'Y',
bookings: []
}
// apply 메서드
// call 메서드를 사용하는 것이 더 낫다
const flightData = [599, 'Google'];
book.apply(yesplane, flightData)
이렇게 배열을 만들어서 함수의 매개변수로 넣어줘야 작동하게 됩니다.
하지만 아래처럼 es6 문법을 사용한다면 call 메서드를 사용해도 똑같이 배열을 넣을 수 있기 때문에
차라리 call 메서드를 사용하는 것이 더 편하다고 생각합니다.
const flightData = [599, 'Google'];
book.call(yesplane, ...flightData)
bind 메서드 사용
bind메서드는 앞의 두 메서드와 다른 차이점을 가지고 있습니다.
call, apply 메서드는 즉시 함수를 호출한다면,
bind 메서드는 새로운 함수를 반환하게 됩니다.
// bind 메서드
// 즉시 함수를 호출하지 않고 새로운 함수를 반환한다
const bookBind = book.bind(airplane);
const bookBind2 = book.bind(planeair);
const bookBind3 = book.bind(yesplane);
이렇게 미리 각 객체마다 사용할 수 있는 함수를 만들어 놓을 수 있기 때문에 사용하기 편할 수 있습니다.
또한 bind 시 매개변수를 마찬가지로 넣어줄 수 있는데, 원하는 매개변수만 지정할 수도 있습니다.
flightNum은 미리 지정하고, name은 나중에 지정해보겠습니다.
// flightNum을 미리 지정하고 name을 지정하지 않으면 원하는 name만 지정할 수 있다
const bookBindN = book.bind(airplane, 23);
bookBindN('working');
bookBindN('good');
예시
event listener의 경우 callback 함수는 해당 element를 가리키게 됩니다.
여기서도 this 키워드가 원하는 airplane 객체를 가리키게 하려면 어떻게 해야할까요?
// with event listeners
// buyPlane이라는 새로운 함수를 생성
airplane.planes = 300;
airplane.buyPlane = function() {
console.log(this)
this.planes++;
console.log(this.planes)
}
document.querySelector('.buy').addEventListener('click', ???)
// 이벤트리스너에 사용된 함수에서의 this 키워드는 해당 element를 가리킨다
// document.querySelector('.buy').addEventListener('click', airplane.buyPlane)
// bind를 사용해서 airplane을 가리키도록 한다
document.querySelector('.buy').addEventListener('click', airplane.buyPlane.bind(airplane))
이렇게 bind 메서드를 사용한다면 airplane 객체를 가리키도록 할 수 있습니다.
'Javascript' 카테고리의 다른 글
| javascript - closure(클로저) 이론과 예시 (0) | 2021.08.22 |
|---|---|
| javascript - first-class function vs higher-order function (0) | 2021.08.20 |
| javascript - string 여러가지 활용 (0) | 2021.08.20 |
| javascript - Map 에 대해 (0) | 2021.08.13 |
| javascript - optional chaining (?.) (0) | 2021.08.13 |