[JS] Call, Apply and Bind methods

JunSeok·2023년 12월 13일
0

Javascript

목록 보기
10/16

first-class citizen & this keyword

  • 함수는 객체의 한 종류이기 때문에 메서드를 가질 수 있다.
    일급시민과 고차원함수 정리
  • 정규 함수(화살표 함수 제외)에서 this 키워드를 사용하게 되면 strict mode에 한에서 this 값은 undefined이다.
  • this 키워드는 호출될 때 값이 정해지는 동적인 값이다. this 키워드 정리
  • 여기서 this 키워드를 수동적으로 정의할 수 있는 방법이 있다.
    함수에 부착된 메서드인 Call, Apply and Bind method를 이용하면 된다.

Call method

const a = {
  name: 'oort',
  booking(one, two) {
    // 여기서 this는 a를 가리킨다.
  	console.log(this.name + `${one} ${two}`
  }
}

// book 변수에 a의 booking 메서드를 재할당
const book = a.booking;
  
// 여기서 this는 undefined이다.
book(1, 2)

// call 메서드의 첫번째 인수는 this 키워드가 가졌으면 하는 값이다.
// 그리고 뒤에 메서드에 필요한 인수들을 입력한다.
book.call(a, 1, 2);
// 정상동작 => oort12
  • 위 예시를 보면 book 이라는 변수에 a 의 메서드인 booking 을 재할당했다.
  • 그리고 book 함수를 호출하면 book 의 소유주는 없기 때문에 book에서 사용한 this 키워드는 undefined 가 된다.
  • this 키워드를 수동으로 정의해주기 위해 call method를 사용한다.
    - 예시를 보면 book 함수를 직접 호출한 것이 아니다.
    - call 메서드가 a 라는 키워드로 book 함수를 호출한 것이다.
  • 모던 자바스크립트에서는 apply 보다는 call 을 사용한다.

Apply method

  • call method와 동작이 같다.
  • 다른 점은 뒤에 올 인수를 배열로 받는다는 것이다.
const a = {
  name: 'oort',
  booking(one, two) {
    // 여기서 this는 a를 가리킨다.
  	console.log(this.name + `${one} ${two}`
  }
}
const book = a.booking;
  
// 여기서 this는 undefined이다.
book(1, 2)

const argu = [1, 2];
book.call(a, argu);

Bind method

const a = {
	name: 'oort',
	book(num, value) {
      	// this === a
		console.log(`${num} ${this.name} ${value}`)
	}
}
const b = {
	name: 'www',
}

// this === undefined
const book = a.book

// this === b
const bookB = book.bind(b)
// 첫번째 키워드는 call과 마찬가지로 this에 할당할 값
// 그 뒤에 인수는 입력이 자유롭다.
// 전부 넣어도 되고, 나중에 넣어도 되고, 일부만 넣어줘도 된다.

// 일부 인수 미리 지정해줄 경우
const bookB = book.bind(b, 12)
bookB('a')
  • bind method 또한 call method와 마찬가지로 this 키워드를 수동으로 설정한다.
  • 차이점은 call은 즉시 함수를 호출하지만 bind는 즉시 그 함수를 호출하지 않는다는 것이다.
  • 대신 원하는 this 키워드가 바인딩된 새 함수를 리턴한다.

bind 함수에서 인수를 미리 지정해줄 수도 있다. 나머지 인수는 호출할 때 넣어주면 된다.(partial application)

  • 이 특성을 활용하여 인수가 미리 지정된 새로운 함수를 만들 때 사용할 수 있다.

  • 아래 예시처럼 this 키워드가 필요없을 때는 null을 넣는 것이 관습이다.

  • 인수의 순서가 중요하다.

  • default parameter와 결과가 비슷해보이지만, bind는 범용 함수에 근거해서 인수를 미리 지정해놓은 새로운 함수를 리턴하는 것이기 때문에 다르다.

    // 범용 함수
    const addTex = (rate, value) => value + rate*value
    
    // 범용함수에 근거해서 인수를 미리 지정해준 새로운 함수
    const addVAT = addTax.bind(null, 0.23);

외부 객체의 메서드를 이벤트리스너의 콜백함수로 사용하는 경우 유용하다.

  • 이벤트리스너의 콜백함수에서 this를 사용할 경우, this는 해당 DOM element를 가리킨다.
  • 때문에 외부 객체의 메서드를 콜백함수로 사용하고자 할 때, this 값을 수동으로 설정할 필요가 있다.
    => 인수로 입력한 값을 this 키워드로 가지는 함수를 리턴하는 bind 메서드를 사용한다.
    document.querySelector('.buy').addEventListener('click', a.book.bind(b))

이벤트리스너의 콜백함수에 인수를 추가할 때 유용하다.

  • 이벤트리스너의 콜백함수는 실행하면 안되고 함수 자체를 넘겨줘야 한다.
  • 그렇기 때문에 기존 파라미터인 event를 제외하면 추가 인수를 넘기는 것은 불가능하다.
  • 하지만 bind 메서드를 이용하여 추가하고 싶은 인수를 this에 할당하는 패턴으로 구현할 수 있다.
    const nav = document.querySelector('.nav')
     // this를 사용하고 싶으면 화살표 함수가 아닌 정규 함수를 사용해야 한다.
     const clickHandler = function(event) {
    	console.log(event.currentTarget) // nav element
       
        // 추가하고 싶은 인수를 bind 메서드를 이용하여 this에 할당하여 사용한다. 
    	console.log(this) // 20
     }
     // 추가하고 싶은 인수를 this에 할당 => this === 20
     nav.addEventListenr('click', clickHandler.bind(20)                              

참조

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function/call
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
https://www.udemy.com/course/the-complete-javascript-course/

profile
최선을 다한다는 것은 할 수 있는 한 가장 핵심을 향한다는 것

0개의 댓글