함수는 단순히 소괄호를 열고 닫는 방법 외에도, 메소드를 이용해 실행할 수도 있습니다.
function foo() {
return 'bar'
}
foo()
foo.call()
foo.apply()
.call
, .apply
호출은 명시적으로 this를 지정하고 싶을 때 사용합니다. 첫번째 인자가 항상 this값이 됩니다.
주의: 지금은 코드 하나하나를 다 이해할 필요 없이 "아 이렇게도 쓸 수 있구나", "생각보다 많이 쓰이는구나" 정도만 이해하고 넘어가도 충분합니다. call의 유용한 예제는 추후에 다룹니다. 다만, 첫번째 인자가 this라는 점만 반드시 기억하고 넘어가세요.
다음은 apply를 이용해 배열 인자를 풀어서 넘기는 예제입니다.
// null을 this로 지정합니다. Math는 생성자가 아니므로 this를 지정할 필요가 없습니다.
Math.max.apply(null, [5,4,1,6,2]) // 6
// spread operator의 도입으로 굳이 apply를 이용할 필요가 없어졌습니다.
Math.max(...[5,4,1,6,2]) // 6
다음은 prototype을 빌려 실행하는 예제를 보여주고 있습니다.
// '피,땀,눈물'을 this로 지정합니다.
''.split.call('피,땀,눈물', ',')
// 다음과 정확히 동일한 결과를 리턴합니다.
'피,땀,눈물'.split(',')
let allDivs = document.querySelectorAll('div'); // NodeList라는 유사 배열입니다.
// allDivs를 this로 지정합니다.
[].map.call(allDivs, function(el) {
return el.className
})
// allDivs는 유사 배열이므로 map 메소드가 존재하지 않습니다.
// 그러나, Array prototype으로부터 map 메소드를 빌려와 this를 넘겨 map을 실행할 수 있습니다.
다음은 객체 지향 프로그래밍에서의 상속을 구현하기 위한 call, apply 사용입니다.
function Product(name, price) {
this.name = name
this.price = price
}
function Food(name, price) {
Product.call(this, name, price)
// 인자가 많으면 Product.apply(this, arguments) 가 더 유용합니다.
this.category = 'food'
}
let cheese = new Food('feta', 5000) // cheess는 Food이면서 Product입니다.