[javascript] call

Published: by Creative Commons Licence

참고

call()

Function.prototype.call()

기존 함수를 재정의하여 원하는 대상에 추가해 그 대상의 메소드인 것처럼 사용할 수 있다. apply()와 동일하지만 2번째 인수의 형태만 다르다.

구문

func.call(thisArg [, arg1, /* …, */ argN])

  • func는 기존 함수.
  • 첫번째 인수 thisArg는 새로운 함수가 추가될 대상이다. 인스턴스를 나타내는 this로 보통은 객체인데 함수나 원시타입 값이 될 수도 있다. null이나 undefined는 전역객체로 원시타입은 객체로 변환된다.
  • arg1, /* …, */ argN 인수들은 새로 만들어질 함수의 파라미터로 사용된다. apply() 2번째 요소로 배열만 받는 것과는 다른 점이다.
  • 반환값은 재정의된 함수의 실행 결과값으로 재정의함수 자체를 반환하는 bind()와 차이가 있다.

예시

printName()obj객체의 메소드처럼 사용을 하고 싶다면 call()을 이용해서 obj를 넘겨준다. 그럼 아래처럼 사용 가능

var name = 'mignon';

var obj = {
  name: 'whale'
}

function printName() {
  return this.name;
}

printName.call(obj); // whale

printName.call(); // mignon, call()에 대상을 넣어주지 않으면 전역객체가 대신한다. 이건 var의 범위가 함수 혹는 전역스코프로 블록단위 제한이 되는 let과 달라서 생기는 현상일수도... 

/*
obj 안에 메서드가 생성된 것처럼 동작하게 된다. 
var obj = {
  name: 'whale',
  printName() {
    console.log(this.name)
  }
}
*/

Array.prototype.map()은 배열에 종속되어 있는 메서드다. 따라서 배열에만 적용이 가능하지만 아래처럼 call()을 이용해 재정의하면 사용가능하다.

var elems = document.querySelectorAll('div');
var values = [].map.call(elems, function(obj) {
  return obj.value;
});

More

apply()
bind()

결론

대상에 없는 메서드를 추가하여 쓰고 싶지만 기존 함수는 변경하고 싶지 않을 때 사용하면 될 듯