#804 enhancement
Adam Terrey

Static Methods

Reported by Adam Terrey | September 17th, 2009 @ 06:15 AM

There have been a few cases where I've needed static methods.

I think this is an appropriate implementation.. Comments?


var MyClass = Class.create ({

  sayCheese: function () {
    // note: "this" is bound to the class generator (MyClass)
    alert ("Cheese!");
  }.setStatic (), // static methods are set using Function#setStatic()

  sayClassType: function () {
    alert ("MyClass");
  }.setStatic (),  

  // an instance method...
  sayMyType: function () {
    this.sayClassType ();
  }

});

var MySubClass = Class.create (MyClass, {

  sayClassType: function ($super) {
    alert ("MySubClass and the parent type is...");
    $super ();
  }.setStatic()
 
});

MyClass.sayCheese ();
MyClass.sayClassType ();
MySubClass.sayClassType ();

var b = new MySubClass ();
b.sayMyType ();
b.sayCheese ();

changes to the code are as follows...

change to Class.create() to extend klass with methods from parent.staticmethods

// ...
// ...
var Class = (function() {
  function subclass() {};
  function create() {

// ...

    Object.extend(klass, Class.Methods);
    klass.superclass = parent;
    klass.subclasses = [];

    // object to hold the static methods
    klass.staticmethods = {}; 

    if (parent) {
      subclass.prototype = parent.prototype;
      klass.prototype = new subclass;
      parent.subclasses.push(klass);

      // extend the current class with the static methods of the parent class
      Object.extend (klass.staticmethods, parent.staticmethods);

      // make the static methods available to the klass namespace
      Object.extend (klass, klass.staticmethods);
    }

change to Class#addMethods() so that functions with staticIsSet are bound to the class generator context and added to the class generator as well as the prototype. Static methods also take advantage of the $super syntax to access their parent methods.

I can't think of a clean way to add static methods after sub classing, so an error is thrown if subclasses have already been made.

// ...
// ...
  function addMethods(source) {
// ...

    for (var i = 0, length = properties.length; i < length; i++) {
      var property = properties[i], value = source[property];

      if (Object.isFunction(value)) {

        // store staticIsSet in case we loose it in the $super wrapper
        var staticIsSet = value.staticIsSet;

        // the isFunction test has been moved from the line below to 4 lines abouve
        if (ancestor && value.argumentNames().first() == "$super") {
          var method = value;
          value = (function(m) {
            return function() { return ancestor[m].apply(this, arguments); };
          })(property).wrap(method);
          value.valueOf = method.valueOf.bind(method);
          value.toString = method.toString.bind(method);
        }

        // Bind to and to the class generator
        if (value.staticIsSet) {
      value = value.bind (this);
      this.staticmethods[property] = value;
          this[property] = value;  
      if (this.subclasses.length > 0)
          throw "Addind a static method after subclassing is not implimented";
        }

      }

      // static methods are also added to the prototype
      this.prototype[property] = value;

    }

And finaly added Function#setStatic () in order to indicate that a function is static.

//...
Object.extend(Function.prototype, (function() {
//...
  function setStatic() {

this.staticIsSet = true;
return this;



}

Comments and changes to this ticket

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile ยป

The Prototype JavaScript library.

Shared Ticket Bins

Attachments

Pages