Rob Kinyon - Class-0.03

Documentation | Source

NAME

Class

DESCRIPTION

This provides a useful way to create classes. See below for more details.

DEPENDENCIES

This requires JSAN and Upgrade to be installed.

JAVASCRIPT CLASSES

There is a lot of confusion about how Javascript implements OO. First off, Javascript doesn't have the idea of a "class" per se. Javascript is a prototype-based language, similar to Self. There are objects and there are methods. There are no classes or functions (more on this later). When you say var foo = new Foo(), what you're really doing is creating a new object using the prototype for Foo (if it has one). When you want to find out what class foo implements, you're really asking "What prototype was foo created from?".

Furthermore, Javascript objects don't have attributes in the same way that Ruby or Python provides. The objects have slots that contain either primitives or other objects. If that object is a function, it acts as a method. So, when you want to add a method to an object, you can add it just by assigning to the slot.

Modifying the prototype is slightly different. When you add something to a prototype, all the objects built from that prototype will be affected. Adding something to an object only affects that object. (This is why many experienced Javascript programmers frown heavily upon modifying Object.prototype or Array.prototype.)

There is no such thing as an independent function in Javascript. Everything is a method, which means that every function has access to a this, referring to the instance that the method was called on. If you don't see an object, the object default to the global scope. In a browser, this is window, but not always.

This distribution simplifies the building of classes by providing a create() method, which creates the class and a extend() method which allows for easy-to-read subclassing. Now, since there are no classes in Javascript, there can be no real subclassing. So, what happens is that you make a copy of the "parent" prototype, then add in the "child's" attributes and methods (which are all just items in slots). This means that any change to the parent's prototype will affect the child's prototype.

STATIC CLASSES

These are classes that are not instantiable, but instead provide a useful set of operations. (In Javascript terms, they do not provide a prototype member, so you cannot call new() upon them.)

Abstract

This class doesn't do anything except provide a useful hook to handle abstract base classe s.

It is deprecated and will be moved to Bundle.Prototype once that distribution is built.

Class

Class provides the following methods:

  • create()
  • This function is used to create new classes. The new class will automatically call its initialize() method, passing all parameters that were passed to the constructor.

      var My.Class = Class.create();
      My.Class.prototype = {
          initialize: function( param1, param2, ... ) {
              this.paramOne = param1;
              this.methodCall( param2 );
              // Do more stuff here
          }
      }
  • extend()
  • This function is used to create subclasses by extending either the class (in the case of abstract classes) or the prototype (in the case of instantiable classes). The child prototype will inherit all the methods and attributes of the parent prototype.

      var My.Child = Class.create();
      My.Child.prototype = Class.extend( My.Parent.prototype, {
          meth1: function () {
              ...
          }
         ,meth2: function () {
              ...
          }
      });

    extend() will also provide access to a __super__ method. In the case of an overridden method, you can use __super__() to access the parent's method. It works as so (using the example above):

      var child = new My.Child();
    
      // This is the child's meth1()
      child.meth1( arg1, arg2 );
    
      // This is the parent's meth1()
      child.__super__( 'meth1', arg1, arg2 );
    
      // This is the grandparent's meth1()
      child.__super__( '__super__', 'meth1', arg1, arg2 );

    This means that Class.extend() will use the __super__ slot in your child's prototype, overwriting anything that you may have put there.

DEPRECATED ITEMS

Abstract is deprecated and will be moved to Bundle.Prototype once Bundle.Prototype exists.

SUPPORT

Currently, there is no mailing list or IRC channel. Please send bug reports and patches to the author.

AUTHOR

Rob Kinyon (rob.kinyon@iinteractive.com)

Originally written by Sam Stephenson (sam@conio.net)

My time is generously donated by Infinity Interactive, Inc. http://www.iinteractive.com

/*

=head1 NAME

Class

=head1 DESCRIPTION

This provides a useful way to create classes. See below for more details.

=head1 DEPENDENCIES

This requires JSAN and Upgrade to be installed.

=cut

*/

try {
    JSAN.use( 'Upgrade.Function.apply' );
    JSAN.use( 'Upgrade.Array.push' );
} catch (e) {
    throw "Class.js requires JSAN to be loaded";
}

/*

=head1 JAVASCRIPT CLASSES

There is a lot of confusion about how Javascript implements OO. First off, Javascript doesn't have the idea of a "class" per se. Javascript is a prototype-based language, similar to Self. There are objects and there are methods. There are no classes or functions (more on this later). When you say C<var foo = new Foo()>, what you're really doing is creating a new object using the I<prototype> for Foo (if it has one). When you want to find out what class foo implements, you're really asking "What prototype was foo created from?".

Furthermore, Javascript objects don't have attributes in the same way that Ruby or Python provides. The objects have slots that contain either primitives or other objects. If that object is a function, it acts as a method. So, when you want to add a method to an object, you can add it just by assigning to the slot.

Modifying the prototype is slightly different. When you add something to a prototype, B<all> the objects built from that prototype will be affected. Adding something to an object only affects that object. (This is why many experienced Javascript programmers frown heavily upon modifying Object.prototype or Array.prototype.)

There is no such thing as an independent function in Javascript. Everything is a method, which means that every function has access to a C<this>, referring to the instance that the method was called on. If you don't see an object, the object default to the global scope. In a browser, this is C<window>, but not always.

This distribution simplifies the building of classes by providing a create() method, which creates the class and a extend() method which allows for easy-to-read subclassing. Now, since there are no classes in Javascript, there can be no real subclassing. So, what happens is that you make a copy of the "parent" prototype, then add in the "child's" attributes and methods (which are all just items in slots). This means that any change to the parent's prototype will affect the child's prototype.

=head1 STATIC CLASSES

These are classes that are not instantiable, but instead provide a useful set of operations. (In Javascript terms, they do not provide a prototype member, so you cannot call new() upon them.)

=cut

*/

/*

=head2 Abstract

This class doesn't do anything except provide a useful hook to handle abstract base classe
s.

It is deprecated and will be moved to Bundle.Prototype once that distribution is built.

=cut

*/

var Abstract = new Object();

/*

=head2 Class

Class provides the following methods:

=over 4

=cut

*/

var Class = {

/*

=item * C<create()>

This function is used to create new classes. The new class will automatically call its initialize() method, passing all parameters that were passed to the constructor.

  var My.Class = Class.create();
  My.Class.prototype = {
      initialize: function( param1, param2, ... ) {
          this.paramOne = param1;
          this.methodCall( param2 );
          // Do more stuff here
      }
  }

=cut

*/

    create: function() {
        return function() { 
            this.initialize.apply(this, arguments);
        }
    }

/*

=item * C<extend()>

This function is used to create subclasses by extending either the class (in the case of abstract classes) or the prototype (in the case of instantiable classes). The child prototype will inherit all the methods and attributes of the parent prototype.

  var My.Child = Class.create();
  My.Child.prototype = Class.extend( My.Parent.prototype, {
      meth1: function () {
          ...
      }
     ,meth2: function () {
          ...
      }
  });

C<extend()> will also provide access to a __super__ method. In the case of an overridden method, you can use __super__() to access the parent's method. It works as so (using the example above):

  var child = new My.Child();

  // This is the child's meth1()
  child.meth1( arg1, arg2 );

  // This is the parent's meth1()
  child.__super__( 'meth1', arg1, arg2 );

  // This is the grandparent's meth1()
  child.__super__( '__super__', 'meth1', arg1, arg2 );

This means that Class.extend() will use the __super__ slot in your child's prototype, I<overwriting> anything that you may have put there.

=cut

*/

   ,extend: function( baseclass, extension ) {
        extension.__super__ = function ( methname ) {
            if ( typeof baseclass[methname] == 'function' ) {
                var args = [];
                for ( var i = 1; i < arguments.length; i++ )
                    args.push( arguments[i] );

                return baseclass[methname].apply( this, args );
            }
        };

        for ( prop in baseclass ) {
            if ( typeof extension[prop] == 'undefined' ) {
                extension[prop] = baseclass[prop];
            }
        }

        return extension;
    }

/*

=back

=cut

*/

};

/*

=head1 DEPRECATED ITEMS

Abstract is deprecated and will be moved to Bundle.Prototype once Bundle.Prototype exists.

=head1 SUPPORT

Currently, there is no mailing list or IRC channel. Please send bug reports and patches to the author.

=head1 AUTHOR

Rob Kinyon (rob.kinyon@iinteractive.com)

Originally written by Sam Stephenson (sam@conio.net)

My time is generously donated by Infinity Interactive, Inc. L<http://www.iinteractive.com>

=cut

*/