이 포스팅은 call(), apply(), bind()에 대해 소개하고 있습니다.
- js에서는 함수 호출 방식과 상관없이 this에 접근할 수 있다.
- 그렇다면 this를 우리가 원하는 객체로 지정할 수는 없을까?
- 이번시간에는 커스텀 this를 지정할 수 있는 세 함수에 대해 알아보자!
1. call(), this를 맘대로 지정할 수 있지
call()
은 모든 함수에서 사용가능하며,this
를 특정 객체로 지정할 수 있다.- 아래 예시는
printDogAge()
에서dog
의age
값을 출력하려고 한다.
const dog = {
age: 12
}
function printDogAge() {
console.log(this.age)
}
- 그런데
printDogAge()
를 호출해보면, 기대한 값은 나오지 않고undefined
가 출력된다.
왜 dog의 age가 출력되지 않는걸까?
dog
의age
가 출력되지 않은 이유는 현재this
는window
를 가리키고 있기 때문이다.- 함수는 별도의 처리를 하지 않으면
this
는window
객체를 가리킨다.
- 그렇다면
this
가dog
를 가리키도록 하려면 어떻게 해야할까? - 바로
call()
을 사용하는 것이다. 호출함수.call(this로_지정할_대상)
을 하면 함수에서 특정 객체를 this로 지정할 수 있다!
const dog = {
age: 12
}
function printDogAge() {
console.log(this.age)
}
printDogAge.call(dog) // 12
- call()을 사용하면, 우리가 기대한 값(12)이 나오게 된다.
여기서 잠깐! 그럼 매개변수를 전달하고 싶으면 call은 어떻게 써야할까?
call()
의 첫 번째 인자가this
로 지정할 객체라면, 두 번째 인자부터는 함수에 넘겨줄 매개변수를 지정할 수 있다.
const dog = {
age: 12
}
function printDogAge(name, location) {
console.log(this.age, name, location)
}
printDogAge.call(dog, 'mike', 'seoul') // 12, mike, seoul
2. apply(), call과 유사하지만 배열을 인자로...
apply()
는call()
과 유사하지만, 매개변수 처리 방법에서 차이가 있다.- 앞서 살펴봤듯이
call()
은 일반적인 함수처럼 매개변수를 받지만,apply()
는 배열형태의 매개변수를 받는다.
const dog = {
age: 12
}
function printDogAge(name, location) {
console.log(this.age, name, location)
}
printDogAge.apply(dog, ['mike', 'seoul']) // 12, mike, seoul
그런데 배열 매개변수를 받는 게 좋은 상황이 있나요?
Math.min()
를 예시로 보자!Math.min()
은 인자로 넘긴 값 중 제일 작은 값을 리턴해주는 함수이다.
const minValue = Math.min(12, 200);
console.log(minValue)
- 그런데 만약 우리가 배열에서 제일 작은 값을 알고 싶다면 어떻게 해야할까?
Main.min()
을 사용하는 경우, spread 연산자를 사용해야 한다.
const arr = [1,23,4,55,231];
const minValue = Math.min(...arr);
console.log(minValue) // 1
- 하지만 배열 그대로 넘고 싶다면? 이 경우
apply()
를 사용하는 것이다. this
로 지정할 객체가 없으므로null
로 지정하고, 두 번째 인자로 배열을 넣어주면 된다.
const arr = [1,23,4,55,231];
const minValue = Math.min.apply(null, arr);
console.log(minValue) // 1
3. bind(), this를 영구적으로 변경할 수 있지
- 우리는 앞서
call()
,apply()
에 대해 알아보았다. - 이 두 메소드는 함수에서 접근할
this
객체를 변경할 수 있었다. - 하지만 커스텀
this
를 영구적으로 가리키도록 할 수 없다.
만약 우리가 커스텀
this
를 가리키는 함수를 만들고 싶다면 어떻게 해야할까?
- 이 경우에는,
bind()
를 사용하면 된다. bind()
는 커스텀this
를 가리키는 함수를 생성할 수 있게 해준다.- 앞선
dog
,printDogAge()
를 예시로 살펴보자!
const dog = {
age: 12
}
function printDogAge(name, location) {
console.log(this.age, name, location)
}
- 우리는
printDogAge()
가this
로dog
를 영구히 가리키게 하고 싶다. - 먼저,
함수.bind(커스텀_this_객체)
방식으로printDogAge
를 특정 변수에 담는다.
const print = printDogAge.bind(dog);
- 이 코드는,
printDogAge()
의this
가dog
인print
함수를 생성한다는 의미이다.
- 이제
print
에 인자를 넣어 호출해보면, 우리가 원하던 결과가 나오게 된다.
print('lala', 'USA') //12 lala USA
이외에도
bind()
는 특정 함수를 더 짧게 만드는 용도로 사용할 수 있다.
js
에서 우리는 데이터의 형태를 출력할거나 테스트할 때console.log
를 자주 사용한다.- 하지만 이
console.log
를 자주 쓰는 상황에서는 이 구문도 길게 느껴질 수 있다. - 이 경우,
bind()
를 사용해 짧은 함수로 만들 수 있다.
const log = console.log.bind(document);
log('test'); // test
log('helloooooo') // helloooooo
오늘 우리는 call, apply, bind에 대해 알아보았다.
call()은 커스텀 this를 지정할 수 있었고, apply()는 call()과 유사하지만 인자로 배열을 받는다는 점에서 차이가 있었다. 마지막으로 bind()는 커스텀 this를 영구히 가지는 함수를 만들 수 있었다.
반응형
'개발 기술 > 개발 이야기' 카테고리의 다른 글
디자인 패턴1, 옵저버란? (0) | 2021.12.08 |
---|---|
클로저는 무엇일까? (feat. 외부, 내부 함수, 랙시컬 스코프) (0) | 2021.11.29 |
랙시컬 스코프(정적 스코프)는 무엇일까? (0) | 2021.11.22 |
promise와 async await의 차이점 (0) | 2021.11.17 |
비동기 처리, promise와 async await (0) | 2021.11.15 |
댓글