본문 바로가기
JS/JavaScript 강의

45. Call and Apply Methods

by 박기린 2022. 11. 29.

안녕하세요. 박기린 입니다.

이번에는 Obejct의 메소드가 아닌 함수에서도 this 키워드를 사용할 수 있게 해주는 내장함수인 call()과 apply()에 대해 알아보겠습니다.

(메소드와 this 키워드에 대한 설명이 있는 글 : https://arnopark.tistory.com/501)

 

 

일반적인 Method 함수와 this 키워드

const lufthansa = {
    airline: 'Lufthansa',
    iataCode: 'LH',
    bookings: [],
    
    book(flightNum, name) {
        console.log(
            `${name} booked a seat on ${this.airline} flight ${this.iataCode}${flightNum}`
        );
        this.bookings.push({ flight: `${this.iataCode}${flightNum}`, name });
    },
};

일반적으로 this 키워드가 사용되는 함수는 Object의 메소드 입니다.
이때 this는 해당 메소드가 포함된 Object를 가리킵니다.

위의 예제 코드는 lufthansa 항공에 대한 정보가 담긴 property와, 예약을 할 수 있는 book 메소드가 담겨 있습니다.

 

 

const book = lufthansa.book;

이제 lufthansa Object의 book 함수를, book이라는 전역함수로 빼내줍니다.

위의 코드를 통해서, book은 메소드를 넘어서 전역함수가 되었습니다.

이제 이 전역함수 book()을 사용해봅시다.

 

book(23, 'Sarah Williams'); // TypeError

메소드 book 함수를 선언했을 때, 'flightNum'과 'name' 만을 인수로 받기로 했습니다. 전역변수가 된 후에도 그대로 넣어줬더니 문제가 발생했습니다.

TypeError가 발생했습니다. property를 읽을 수 없다고 합니다.

 

console.log(
    `${name} booked a seat on ${this.airline} flight ${this.iataCode}${flightNum}`
);
this.bookings.push({ flight: `${this.iataCode}${flightNum}`, name });

book 함수의 내부는 이런 코드로 이루어져 있습니다.

여기서 property는 'this' 키워드로부터 나옵니다. lufthansa Object의 메소드였던 book은 this가 원래는 lufthansa Object를 연결해줬기에,

'this.airline' -> 'lufthans.airline'

이러한 형식으로 자동으로 변환이 될 수 있었습니다.

 

하지만 book이 메소드가 아니라 전역함수로 빠지면서, this 키워드가 갈 곳을 잃어버린 것입니다. 그래서 TypeError가 발생합니다.

이 문제를 해결하기 위해선 book()의 this 키워드를 어떠한 다른 Object와 연결해줄 필요가 있습니다.

그때 사용할 수 있는 내장함수가 있습니다. 바로 call()apply() 입니다.

 

 

 


Function.prototype.call()

const eurowings = {
  airline: 'Eurowings',
  iataCode: 'EW',
  bookings: [],
};

이번엔 eurowings라는 항공의 정보가 담긴 Object를 만들어줍니다.

그리고 여기에 book()과 연결을 해주겠습니다.

 

 

 

book.call(eurowings, 23, 'Sarah Williams');
console.log(eurowings);

book.call(lufthansa, 239, 'Mary Cooper');
console.log(lufthansa);
함수명.call(object, ...원래 함수에 필요한 인수들);

위와 같은 구조로 call() 내장함수를 불러주면, this 키워드에 call()의 첫 번째 인수로 넘긴 object를 연결해줍니다.

 

 

실행 결과물

 

 


Functions.prototype.apply()

apply()는 call()과 똑같은 기능을 합니다.

차이점이라고 한다면, call()은 인수 목록apply()는 인수 Array 하나를 받는다는 점이 있습니다.

 

const swiss = {
    airline: 'Swiss Air Lines',
    iataCode: 'LX',
    bookings: [],
};

이번엔 swiss 항공의 정보가 담긴 object를 만들어줍니다.

 

book.call(swiss, 583, 'Mary Cooper');

call() 함수를 사용한다면, 위의 코드처럼 object를 먼저 인수로 넘긴 후, book 함수가 필요로 하는 인수들을 차례대로 넘길 것입니다.

 

 

const flightData = [583, 'George Cooper'];
book.apply(swiss, flightData);

 

함수명.apply(object, Array of arguments);

apply()는 첫 번째 인수로는 this 키워드로 연결해줄 object를 받습니다. 이는 call()과 동일합니다.

두 번째 인수로는 'Array of arguments' - 원래 함수에 필요한 인수들을 담은 Array를 받습니다.

 

실행 결과물

 

 

 

+ Array of arguments를 스프레드 연산자로 풀어서 call()에 전달하는 방법도 있습니다.

book.call(swiss, ...flightData); 
실행 결과물
반응형