Rev. 2.73

요즘 kangax씨의 블로그를 즐겨 보고 있습니다. 배울점이 참 많네요. 다음 내용은 PrototypeClass.create를 이용해서 생성한 함수에서 비롯된 작은 불만을 해결하는 내용을 담고 있습니다.

객체를 검증하는 가장 쉬운 방법 중 하나는 바로 문자열로 변환하는 것 입니다. 아래처럼 말이죠.

function foo() { 
  return 'foo'; 
} 
foo + ''; // "function foo(){ return 'foo'; }" 
// or 
foo.toString(); 
// or 
String(foo);

Prototype의 Class.create로 생성된 함수들은 아래와 같은 무의미한 문자열을 반환합니다.

var Person = Class.create({
  initialize: function(name) {
    this.name = name;
  },
  speak: function(msg) {
    return this.name + ' says: ' + msg;
  }
});
 
Person + ''; // "function klass() { this.initialize.apply(this, arguments); }"
 
var Employee = Class.create(Person, {
  initialize: function($super, dept) {
    $super();
    this.dept = dept;
  }
});
 
Employee + ''; // "function klass() { this.initialize.apply(this, arguments); }"

보시다시피, Class.create 메서드의 초기화 함수 코드만을 보여주는 것입니다. 실제 생성자-함수 코드를 보려면 "initialize" 메서드를 직접 찾아가는 수 밖에 없습니다.

// nothing new here
Person + ''; // "function klass() { this.initialize.apply(this, arguments); }"
 
// and the actual code
Person.prototype.initialize + ''; // "function (name) { this.name = name; }"

이것이 바로 출력되기를 바랬던 문자열 입니다. 이와 같이 검증하는 것은 때때로 짜증을 유발하죠. 그래서 아래와 같이 Class.create 메서드를 패치(monkey-patch)하였습니다.

Class.create = (function(original) {
  var fn = function() {
    var result = original.apply(null, arguments);
    result.toString = function() { return result.prototype.initialize.toString() };
    return result;
  };
  fn.toString = function(){ return original.toString() };
  return fn;
})(Class.create);

기존 메서드의 기능을 그대로 살리면서 "toString" 메서드 호출을 생성자-함수(prototype.initialize)의 것으로 교체하는 방법으로 최대한 간결하게 패치한 것입니다.

// monkey-patch Class.create first...
 
// Person.toString now yields much more informative result
Person + ''; // "function (name) { this.name = name; }"
 
// Class.create code seems to be unchanged
Class.create + ''; // outputs actual Class.create code

덧. apply메서드의 첫번째 인자가 'null'인 경우 전역 객체가 전달 된다는 사실을 이제서야 알았습니다.

Comments

Got something to add? You can just leave a comment.

Your Reaction Time!

captcha

avatar