2016년 10월 12일 수요일

[javascript patterns][콜백과 유효범위]스터디 04

이전의 예에서, 콜백은 이런 식으로 실행했다.
var a = function() {
  callback(parameters);
}
이 코드는 간단하고 대부분의 경우 훌륭하게 작동한다. 그러나 콜백이 일회성의 익명 함수나 전역 함수가 아니고 객체의 메서드인 경우도 많다.
var a = function() {
var myapp = {};
myapp.color = 'green';
myapp.paint = function (node) {
  node.style.color = this.color;
};

var findNodes = function(callback) {
  //...
  if (typeof callback === 'function') {
    callback(found);
  }
//...
};
findNodes(myapp.paint);

이러면 작동하지 않는다. findNodes(myapp.paint)를 호출하면 this.color가 정의되지 않아 예상대로 동작하지 않는다.
findNodes()가 전역 함수이기 때문에 객체 this는 전역 객체를 참조한다. findNodes()가 (dom.findNodes()처럼) dom이라는 객체의 메서드라면, 콜백 내부의 this는 예상과는 달리 myapp이 아닌 dom을 참조하게 된다.(this에 대해 자세히 공부를 해야함)

이 문제를 해결하려면, 콜백 함수와 콜백이 속해 있는 객체를 함.께. 전달하면 된다.

findNodes(myapp.paint, maapp);
var findNodes = function (callback, callback_obj) {
  //...
  if (typeof callback === 'function') {
    callback.call(callback_obj, found);
  }
  //...
};

이것을 바인딩(binding)이라고 하는데 저 위에 사용해본 call(), apply() 가 바인딩을 위해 사용되는 것인데, 나중에 더 공부해보도록 하자.

콜백으로 사용될 메서드와 바인딩할 객체를 전달할 때, 메소드를 문자열로 전달 할 수도 있다. (이렇게 하면 객체를 두 번 반복하지 않아도 된다. 무슨말이냐면!

findNodes(myapp.paint, myapp);
여기서
findNodes("paint", myapp);
이렇게 바꿀 수 있는데, 이 두 방법에 모두 대응하는 findNodes()를 만드려면?!
var findNodes = function (callback, callback_obj) {
  if (typeof callback === 'string') {
    callback = callback_obj[callback];
  }
  //...
  if (typeof callback === 'function') {
    callback.call(callback_ovj, found);
  }

댓글 없음:

댓글 쓰기