[JS] 자바스크립트 apply, call 개념, 활용 예제

2023. 4. 13. 23:52개발/HTML+CSS+JS

this와 아이들 (apply, call, bind)

apply, call, bind는 지난 자바스크립트 실행컨텍스트 글 this bind에서 다루었다.
그럼에도 다시 글을 쓰는 이유는 call과 apply는 기본적으로 Function.prototype의 메서드이며 this를 바인딩하는 기능이 있지만 기본적으로 함수를 호출하는 메서드 이기 때문이다.

Function.prototype.apply/ Function.prototype.call

this로 사용할 객체와 함께 호출할 함수의 인수를 전달한다.

/** 
 * apply
 * @param {} this로 사용하고자 하는 객체
 * @param [arg1, arg2, ...] 함수에게 전달할 인수 목록
 */

/** 
 * call
 * @param {} this로 사용하고자 하는 객체
 * @param arg1, arg2 ... 함수에게 전달할 인수 목록
 */

var logThis = function(a,b){
    console.log(" > ",Object.keys(this)[0])
    console.log(this.objX)
}

// this로 사용할 객체 {objX:'~~~'}
logThis.apply({objX:'명시적바인딩이 된다'},["test","apply"])
logThis.call({objX:'명시적바인딩이 된다'}, "test","call")

호출할함수.메서드({객체}, 인수)

기본적으로 apply, call은 함수를 즉시 실행하는 메서드로 주로, 명시적 바인딩을 하기 위해 사용하지만 이를 활용해서 몇가지 다른 효과를 가져올 수 있다.

apply, call 활용

유사객체 배열

// 유사배열 객체
var likeArrayObj = {
    0: 'a',
    1: 'b',
    2: 'c',
    length: 3
};

Array.prototype.push.call(likeArrayObj, 'd');

유사배열 객체가 주어졌을 때 ES6에서 추가된 문법인 Array.from을 사용하지 않더라도 유사배열 객체를 배열로 변환해 준다.

Array.prototype.push.call(likeArrayObj, 'd');

likeArrayObj를 콘솔로그 찍으면 다음과 같다.
한 줄로 나오지만 보기 쉽게 여러줄로 작성해 보았다.

{ '0': 'a',
'1': 'b',
'2': 'c',
'3': 'd',
length: 4 }

이렇게 객체를 배열처럼 값을 추가하며 사용할 수 있게 된다.

하지만 ES6에서 Array.from으로도 동일한 기능을 구현할 수 있게 되었다.

var goAwayIief = Array.from(likeArrayObj)
console.log(goAwayIief)

goAwayIief을 콘솔로그 찍으면 다음과 같다.

[ 'a', 'b', 'c', 'd' ]

코드의 재사용성 활용

function Actor(name, debut, majorMovie){
    this.name = name
    this.debut = debut
    this.majorMovie = majorMovie
}
function Singer(name, debut, majorSong){
    this.name = name
    this.debut = debut
    this.majorSong = majorSong
}

이러한 생성자 함수가 있을때 중복되는 코드를 줄이고 재사용성을 높일 수 있다.

function Entertainer(name, debut){
    this.name = name
    this.debut = debut
}
function Actor(name, debut, majorMovie){
    Entertainer.call(this, name, debut);
    this.majorMovie = majorMovie
}
function Singer(name, debut, majorSong){
    Entertainer.apply(this, [name, debut]);
    this.majorSong = majorSong
}

var myFavoriteMovieStar = new Actor('유덕화', 1981, '천장지구')
var myFavoritePoPStar = new Singer('이효리', 1998, 'U-Go-Girl')

console.log(myFavoriteMovieStar)
console.log(myFavoritePoPStar)

this 를 바로 넘기는 즉시함수 콜을 사용해서 위와 같이 변경할 수 있다.

코드의 길이는 길어지지만 중복되는 부분을 줄여서 재사용성을 높였다고 볼 수 있다.