[Effective JavaScript] 고정된 수신자 객체로 메서드를 추출하기 위해 bind를 사용하자

김범식·2023년 7월 6일
0

문제

다음과 같은 함수가 있다고 가정해보자

var buffer = {
	entries : [],
	add : function(s){
		this.entries.push(s); //배열에 값 추가 
	},
	concat:function(){
		return this.entries.join(""); //문자열로 만들기 
	}
}

forEach 메서드를 사용하면 적용할 대상 배열의 각 요소에 대해 반복 호출하여 문자열로 된 배열을 buffer로 복사할 수 있을 지도 모른다

var source = ["010","-","1234","-","6789"];
soruce.forEach(buffer.add); //buffer에 있는 add 함수를 사용하겠다는 뜻

//오류 entries 가 정의되지 않음 

여기서 buffer.add를 사용하긴 하지만 해당 함수의 수신자 객체는 buffer가 아니다. forEach의 구현은 전역 객체를 디폴트 수신자 객체로 사용한다. 그리고 그 전역객체는 entries 프로퍼티를 가지고 있지 않기 때문에, 이코드는 에러를 발생시킨다.



해결방법

래퍼 함수 명시적으로 생성하기

지역함수를 만들고 buffer.add()를 호출해서 사용하는 방법이 있다.

var source = ["010","-","1234","-","6789"];
soruce.forEach((s)=>{
	buffer.add(s);
});

buffer.join(); //'010-1234-6789'



bind 매서드 사용하기

bind 매서드를 사용하면, 수신자 객체를 받아들이고 원본 함수를 수신자 객체의 메서드로써 호출하는 래퍼함수를 만들 수 있다.

var source = ["010","-","1234","-","6789"];
soruce.forEach(buffer.add.bind(buffer));  //add 함수 안의 this를 buffer로 고정시킨 함수를반환하게 된다. 
buffer.join(); //'010-1234-6789'

buffer.add.bind(buffer) 는 buffer.add 함수를 수정하지 않고 새로운 함수를 만들게 된다. 이전함수와 동일하게 동작하지만 수신자 객체가 buffer로 바인딩 되었다.

buffer.add === buffer.add.bind(buffer) //false



기억할 점

  • 메서드 추출이 메서드 수신자 객체를 해당 객체로 바인딩 하지 않는다.
  • 객체의 메서드를 고차 함수로 전달할 때, 익명 함수를 사용해서 적절한 수신자 객체에 메서드로 호출될 수 있게 하라
  • 적절한 수신자 객체로 바인딩 되는 함수를 간단하게 만들기 위해 bind 메서드를 사용하라
profile
frontend developer

0개의 댓글