요즘 kangax씨의 블로그를 즐겨 보고 있습니다. 배울점이 참 많네요. 다음 내용은 Prototype의 Class.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!