bind 구현해보기

IT공부중·2021년 3월 17일
1

JavsScript

목록 보기
20/22

bind는 this 값을 특정한 값으로 고정시킨 함수를 만들 수 있는 메소드이다.
bind는 ES5에 추가되었기 때문에 ES5 이전에는 call, apply를 통해서만 this를 변경할 수 있었다. bind처럼 this를 변경 한 함수로 만들기 위해서는 직접 구현을 했어야했다.
그러면 call, apply와 클로저를 활용해서 bind와 똑같이 구현하게 만들어볼 것이다.

bind 구현

Function.prototype.bind = function(target, ...args) {
	if(typeof this !== 'function') throw new Error('함수가 아닙니다.');
  	const that = this;
  	return function(...rest){
    	return that.call(target, ...args, ...rest);
    }
}

이렇게 작성하면 기존의 bind와 똑같이 작동하는 것을 확인할 수 있을 것이다.
that은 return으로 일반 함수를 반환할 경우 this값이 바뀔 수 있으므로 클로저로 저장해놓은 것이다. 또는 화살표 함수를 사용하면 된다.

Function.prototype.bind = function(target, ...args) {
	if(typeof this !== 'function') throw new Error('함수가 아닙니다.');
  	return (...rest) => this.call(target, ...args, ...rest)
}

하지만 첫번째 function은 화살표 함수로 변경하면 안 된다! 화살표함수의 this는 lexical this로 선언시의 this로 고정되어 버리기 때문에 일반 모드일 경우 winodw or global, use strict 인 엄격모드일 경우에는 undefined가 되어 에러가 날 것이다.

rest 문법과 화살표 함수는 ES6문법이다. ES5 이전 문법으로 하려면 어떡해야할까? arguments를 사용해볼 수 있을 것 같다.

Function.prototype.bind = function(target) {
	if(typeof this !== 'function') throw new Error('함수가 아닙니다.');
    var args = Array.prototype.slice.call(arguments, 1);
    var that = this;
  	return function(){
        var rest = Array.prototype.slice.call(arguments);
        return that.apply(target, args.concat(rest))
    } 
}

call은 , 를 기준으로 들어가야하는데 spread 문법을 못 쓰니 펼칠 방법이 생각나지 않더라. 그래서 apply를 사용하고 concat을 이용해서 배열 형식으로 넣어주는 방식을 택했다. call, apply가 나눠진게 이 이유가 아닐까 생각해본다.

해당 bind는 제가 생각해서 짠 것이므로 모든 상황에 돌아가지 않을 수도 있습니다. 정확한 참고는 https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
에 polyfill 부분을 참고하면 좋을 것 같습니다!

profile
4년차 프론트엔드 개발자 문건우입니다.

0개의 댓글