하루에 한 문제

call, apply 본문

카테고리 없음

call, apply

dkwjdi 2021. 4. 8. 23:41

앞서 자바스크립트에서 함수 호출이 발생할 때 상황에 따라 this가 바인딩 되는것을 보았다.

자바스크립트에서는 내부적인 this바인딩 이외에도 this를 특정 객체에 명시적으로 바인딩시키는 방법이 있다.

바로 apply(), call() 메서드다

이 메서드들은 모든 함수의 부모 객체인 Function.prototype 객체의 메서드이므로 모든 함수가 호출가능하다.

 

 

function.apply(thisArg, argArray)

  • apply() 메서드를 호출하는 주체는 함수이다.
  • apply() 메서드도 this를 특정 객체에 바인딩할 뿐 결국 본직적인 기능은 함수호출이다.
  • 예를 들어 Person()이라는 함수가 있고, Person.apply() 이렇게 호출한다면 이것의 기본적인 기능은 Person() 함수를 호출하는것이다.
  • 첫 번째 인자 thisArg는 apply() 메서드를 호출한 함수 내부에서 사용한 this에 바인딩할 객체를 가리킨다.
  • 즉 첫 번째 인자로 넘긴 객체가 this로 명시적으로 바인딩 되는것이다.
  • 두 번째 인자인 argArray는 함수를 호출할 때 넘길 인자들의 배열을 가리킨다.
//생성자 함수
function Person(name, age, gender){
    this.name = name;
    this.age = age;
    this.gender = gender;
}

//foo빈 객체생성
var foo = {};
//apply()메서드 호출
Person.apply(foo, ['foo', 30, 'man']);
console.dir(foo);

  • foo는 객체 리터럴 방식으로 생성한 빈 객체다.
  • apply() 메서드를 사용해서, Person()함수를 호출했다.
  • 첫 번째 인자로 넘긴 foo는 Person()함수에서 this로 바인딩된다.
  • 두 번째 인자로 넘긴 ['foo'30'man']은 호출하려는 Person()함수의 인자로 전달된다.
  • 이 코드는 결국 Person('foo', 30, 'man')함수를 호출하면서, this를 foo객체에 명시적으로 바인딩하는 것을 의미한다.

 

call()메서드는 apply()와 기능은 같지만 두 번째 인자에서 배열 형태로 넘긴것을 각각 하나의 인자로 넘긴다.

//생성자 함수
function Person(name, age, gender){
    this.name = name;
    this.age = age;
    this.gender = gender;
}

var bar = {};
Person.call(bar, 'bar', 23, 'woman');
console.dir(bar);

 

 

 

apply(), call()메서드는 this를 원하는 값으로 명시적으로 매핑해서 특정 함수나 메서드를 호출할 수 있다

  • 이들의 대표적인 용도가 바로 arguments객체에서 설명한 유사 배열 객체에서 배열 메서드를 사용하는 경우이다.
  • arguments객체는 실제 배열이 아니므로 pop(), push()같은 표전 배열 메서드를 사용할 수 없다.
  • 하지만 apply()를 이용하면 가능하다!
function myFunction() {
    console.dir(arguments);

    //arguments.shift() 오류발생

    //arguments 객체를 배열로 변경
    var args = Array.prototype.slice.apply(arguments);
    console.dir(args);
}

myFunction(1, 2, 3);

코드를 해석해보자

  • Array.prototye.slice()메서드를 호출해라. 이때 thisarguments객체로 바인딩해라!
  • 즉, argumetns객체가 Array.prototye.slice()메서드를 마치 자신의 메서드인 양 사용할 수 있다는 것이다.
Comments