얼마전에 PrototypeJS가 1.6.0_rc0 버전이 공개되었습니다.
홈페이지에 공개된 내용은 간략하게 되어있어 어떤면이 변했는지 감으로만 알 수 있을뿐, 직접 코딩해보지 않으면 알 수 없는 법이므로 어떻게 달라졌는지 알아보도록 하겠습니다.

var Prototype = {
  Version: '1.6.0_rc0',
  Browser: {
    IE:     !!(window.attachEvent && !window.opera),
    Opera:  !!window.opera,
    WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
    Gecko:  navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1,
    MobileSafari: !!navigator.userAgent.match(/iPhone.*Mobile.*Safari/)
  },
 ...........
}

if (Prototype.Browser.MobileSafari)
  Prototype.BrowserFeatures.SpecificElementExtensions = false;



우선 처음부분에서 달라진건 역시 버전이군요 ^^; 그리고 밑에 보면 모바일사파리라고 해서 아이폰에 대비한 모습도 보이는군요. 이제는 모바일 디바이스도 지원해야하는 세상이네요..ㅎㅎ 허나 제가 아이폰이 없는관계로 테스트는 --;; 못하겠습니다.

그다음에 크게 바뀐 것중 하나가 Class 쪽입니다.
기존에는 단순하게
var Class = {
  create: function() {
    return function() {
      this.initialize.apply(this, arguments);
    }
  }
}
이와 같은 형태였으나, 지금은 확 바뀌었군요. Class 관련 전체 코드는 아래와 같습니다.

var Class = {
  create: function(parent, methods) {
    if (arguments.length == 1 && !Object.isFunction(parent))
      methods = parent, parent = null;

    var method = function() {
      if (!Class.extending) this.initialize.apply(this, arguments);
    };

    method.superclass = parent;
    method.subclasses = [];

    if (Object.isFunction(parent)) {
      Class.extending = true;
      method.prototype = new parent();

      parent.subclasses.push(method);

      delete Class.extending;
    }

    if (methods) Class.extend(method, methods);
    method.prototype.constructor = method;

    return method;
  },

  extend: function(destination, source) {
    for (var name in source) Class.inherit(destination, source, name);
    return destination;
  },

  inherit: function(destination, source, name) {
    var prototype = destination.prototype, ancestor = prototype[name],
     descendant = source[name];
    if (ancestor && Object.isFunction(descendant) &&
        descendant.argumentNames().first() == "$super") {
      var method = descendant, descendant = ancestor.wrap(method);
      Object.extend(descendant, {
        valueOf:  function() { return method },
        toString: function() { return method.toString() }
      });
    }

    prototype[name] = descendant;

    if (destination.subclasses && destination.subclasses.length > 0) {
      for (var i = 0, subclass; subclass = destination.subclasses[i]; i++) {
        Class.extending = true;
        Object.extend(subclass.prototype, new destination());
        subclass.prototype.constructor = subclass;
        delete Class.extending;
        Class.inherit(subclass, destination.prototype, name);
      }
    }
  },

  mixin: function(destination, source) {
    return Object.extend(destination, source);
  }
};

무척이나 많이 바뀌었네요. 여기서 소스를 하나하나 뜯는것 보다, 바로 써먹을 수 있는것에 초점을 두겠습니다.
PJS 사이트에 예제가 하나 나와있긴하나 미완성 예제(제생각에 ^^)라 판단되어 조금 덧붙여봤습니다.
<script>
var Animal = Class.create({  
 initialize: function(name) {    
  this.name = name;  
 },  
 eat: function() {    
  return this.say("Yum!");  
 },  
 say: function(message) {   
  return this.name + ": " + message;  
 }
});

// subclass that augments a method
var Cat = Class.create(Animal, {  
 eat: function($super, food) {    
  if (food instanceof Mouse) return $super();    
  else return this.say("Yuk! I only eat mice.");  
  }
});

var Mouse = Class.create(Animal, {});
var Dog = Class.create(Animal,{})

var tom = new Cat('Toml');
var jerry = new Mouse('Jerry');
var goopy = new Dog('Goopy');

alert(tom.eat(jerry));
alert(tom.eat(goopy));

</script>

실행결과는 ? 그렇습니다. 첫번째 alert에는 Yum!, 다음 alert에는 Yuk! I only eat mice 라고 나옵니다.
여기서 중요한건 무엇일까요? 바로 메소드 오버라이드(override)가 가능하다는 것입니다. 오버라이드가 기본적으로 가능하려면,
클래스사이의 관계 즉, 수퍼클래스와 서브클래스의 개념을 지원해야 가능하다는 것이지요. 기존 1.5.1에서 클래스 상속이라고 했던것들은 모두 기존 메소드들의 대체였다면, 이번 버전에서의 상속은 같은 이름의 메소드가 있을경우 오버라이드 시키고 있습니다. PJS가 좀더 OOP에 한발짝 다가섰군요.

해당 소스의 자세한 분석은 다음에 하기로 하고 계속 되는 포스트에는 사용법에 맞춰 작성될것입니다.
요즘 하는일이 하도 많아서 언제쯤 분석하고 올릴 수 있을지 모르겠지만 ^^; 언젠가는 하겠죠? ㅎㅎ

posted by blankus

태그 - ,
Tip  |  2007/08/18 20:38
이 글의 트랙백 주소 :: http://www.blankus.net/trackback/26
2007/10/08 17:59 댓글에 댓글수정/삭제
방금 아이팟 터치가 도착해서 alert(Prototype.Browser.MobileSafari)를 찍었더니 "false"를 토하더군요; 아래처럼 변경하니 잘되덥니다.

MobileSafari: !!navigator.userAgent.match(/(iPhone|iPod).*Mobile.*Safari/)

아마도 iPhone 대신에 iPod이 들어간서 인가 봅니다.
2007/11/01 17:29 수정/삭제
좋은 정보 감사합니다..^^ 아이팟하고 별로 친하지 않다보니..거깃까진..ㅎㅎㅎ 앞으로 개발할때 참고해야겠네요
.
스크린
2008/01/20 13:41 댓글에 댓글수정/삭제
이번 회사 프로젝트때 prototype.js와 jsgraphics.jp 라이브 라이브 러리를 사용 하려고 하는데 MIT 라이센스더라구요......그냥 사용 해도 상관 없나요? GPL을 계속 사용 했는데 MIT는 처음이라서....
2008/01/24 12:04 수정/삭제
네 그냥 사용하셔도 됩니다 ^^ 단 소스를 수정하지는 마시구요 주석도 손대지 마시구요 ^^
.
이름 ::   비밀번호 :: 홈페이지 :: 비밀글
등록