2015년 6월 29일 월요일

javascript bind는 무엇인가?

아래의 질문에 대해 답해보자!
function foo() {};
foo.bind(this) !== foo.bind(this);
false
왜일까? 문제를 좀더 간단하게 바꾼 후 생각해보자
var a = {};
var b = {};
//묵시적으로 인터프리터에서 아래 문장으로 변환후 처리
//var a = new Object();
//var b = new Object();
a === b (a == b) 인가?
아니다 왜냐하면 a 와 b 는 다른 object 이기 떄문이다.
아래 주석처리된 부분을 보면 명확해 진다.
하나의 클래스에서 populate 된 두개의 다른 instance 이기 때문이다.(각기 다른 메모리 주소를 레퍼런스로 가지고 있다.)
Features of comparisons:
If both operands are objects, then JavaScript compares internal references which are equal when operands refer to the same object in memory
(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators)
위의 문장이 이해가 되었다면 아래 문장을 생각해보자
function foo() { console.log(this); console.log(arguments)};
var obj = {};
var a = foo.bind(obj,1);
var b = foo.bind(obj,1);
a(2,3);//1,2,3
b(2,3);//1,2,3
a === b
즉 2개의 새로운 함수를 생성한 후 위와 같이 두개의 래퍼런스가 같니라고 물어보는 상황인 것이다.
즉 false 가 나와야 함이 명확하다.
하지만 bind가 조금 애매하다.. 머하는 놈이었는지….
그럼 좀더 bind가 머하는 애인지 살펴보자!
Function.prototype.bind()
The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.
(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind)
즉 새로운 함수를 생성하는대 해당 함수의 this 키워드를 주어진 argument의 첫번째 값으로 설정한 함수를 돌려 준다.
그후에 정의된 파라미터가 있으면 이후 호출시 해당 value를 미리 채워서 넘겨준다 라고 설명되어있다.
위의 설명을 확인하면 Function.prototype.bind 라는 함수는 아래처럼 정의 될수있다.
Function.prototype.bind = function() {  
  var _this = this;
  var outArg = Array.prototype.slice.call(arguments,0);
  return function() {
      var inArg = Array.prototype.slice.call(arguments,0);
    return _this.apply(outArg[0], outArg.slice(1).concat(inArg));
  }
}
var obj = {};
var a = foo.bind(obj,1);
var b = foo.bind(obj,1);
a(2,3);//1,2,3
b(2,3);//1,2,3
실재로 실행해보면 두개의 결과가 동일하다는걸 알 수 있다.
그렇다면 이제 처음 질문으로 돌아가 보자
function foo() {};
foo.bind(this) !== foo.bind(this);
여기서 this는 global object이기 때문에 host의 최상위 객체를 집어넣는다.
브라우저의 경우 window 이다.
즉 같은 파라미터를같는 두개의 펑션의 인스턴스를 생성한 후 두개의 인스턴스가 같니?
라는 질문이기 때문에 false 가 나와야 함이 자명하다!