You'll find on this page documents that will help you learn, use and develop with Extend.
Extend 2.0 manual is included below for your on-line reading pleasure !
Extend 2.0 is an evolution of Extend 1.0 which implements a flexible class-based OOP layer on top of the JavaScript prototype object model.
Extend 2.0 allows you to write nice and clean classes in JavaScript, features introspection and class meta-information, is mature and fully-tested, and used as a base for our wonderful Sugar language runtime.
JavaScript being a prototype-based object language, it does not offer (in standard) a “class-based” OOP layer. This can become a problem when you're writing medium to large system, where prototypes start to be cumbersome to manage.
The famous JavaScript Prototype library provides a very basic way to create classes, but does not provide any inheritance between classes. Extensions such as ExtendClass and ExtendClassFurther tried to add sub-classing, but fail to have a flexible and reliable super-equivalent, which makes advanced JavaScript application development difficult.
Moreover, neither of these extensions allow meta-information specification to classes (such as class name, methods, parent class, etc), while this information is very useful for debugging and introspection.
Additionally, common cases such as handing an object method to a callback that may alter the this is not supported (jQuery callback do that).
Extend 2.0 is a simplified, cleaner version of the Extend 1.X library, with the same design goals:
To start using Extend, simply add the following line to your HTML head section:
<script type="text/javascript" src="http://www.ivy.fr/extend/extend.js"></script>
Once you've included the script, you can create classed by using the 'Extend.Class' function:
var A = Extend.Class({
name:"A",
methods:{
helloWorld:function(){
return "Hello, World !";
}
}
});
alert(new A().helloWorld());The Extend.Class takes the following parameters, given in a dictionary:
name (required): a string representing the class name. In case you want the class name to reflect a package hierarchy (like ui.widget.InputField), you can use dots to join module names and class name.parent: the parent class (if any) of this class.initialize: the constructor function for this class.properties: a dictionary mapping instance declaring attributes (properties) (and their optional default values).methods: a dictionary mapping method names to functions implementing the methods, where the this will refer to the current instance.shared: a dictionary mapping class attributes names to values. Class attributes default values are inherited by sub-classes, and can be accessed directly (like A.foo if foo is a class attribute of A)operations: a dictionary mapping class methods (operation) names to functions. The this in these functions will refer to the class object, as returned by Extend.Class.In methods, you this will (obviously) point to the current instance. If you want to access the method foo defined in class A, when you are in class B subclass of A, you can do:
this.getSuper(A).foo()
or use the faster option:
this.A_foo()
where A is the name you gave to the class A.
Extend offers a set of methods that can are available to Extend classes and instances created from Extend classes. These methods range from simple introspection (what is the class of an object, what is this class name, is this an object an instance of this class, etc) to more complex things (safely wrapping a method for callback, listing inherited methods, etc).
Extend.Class({...})Extend.getClass(name:String)Extend.getClasses()Extend.getChildrenOf(aClass)aClass). This excludes the given class from the result.The object API defines the methods which are available to instances (objects) which were created (instantiated) from a class defined using Extend.
isClass()falsegetClass()getMethod(name:String)object.method, then you may have problems when the caller changes the this argument of the method. Using getMethod will ensure that the this is preserved. It's actually an equivalent of doing 'this.getClass().bindMethod(this, name)', except that successive calls to 'getMethod(…) will always return the same function object, while
bindMethod' will create a new function each time (useful to know when you're using jQuery 'bind'/'unbind' functions).getCallback(name:String)getCallback method is similar to getMethod, except that it will add an extra argument which is the this used when invoking the method. Libraries such as jQuery change the this of callbacks given to events such as click or focus to the DOM node that received the event rather than the instance to which the method is bound. Using getMethod insulates you from this change, but you also lose the reference to the DOM node that received the event (the event target). When using getCallback, you'll have the target as an additional argument.getSuper(c:Class)isInstance(c:Class)true if this instance is an instance of the given class, which must be either the class of this instance, or an ancestor of this instance class.The class API defines the methods which are available for class objects resulting from the use of the Extend API.
isClass()truegetName()getParent()undefined.hasInstance(o:Object)isSubclassOf(c:Class)listMethods(own:Boolean=True, inherited:Boolean=True)own methods and the inherited methods. Settings these two parameters to either true or false will allow to return the desired subset.listOperations(own:Boolean=True, inherited:Boolean=True)listMethods, but with class operations.listShared(own:Boolean=True, inherited:Boolean=True)listMethods, but with class attributes (“shared”).listProperties(own:Boolean=True, inherited:Boolean=True)listMethods, but with instance attributes (“properties”).getOperation(name:String)this will be preserved even if you use operation.apply(other_object,
arguments) (pretty much like bindMethod).bindMethod(o:Object, name:String)name when it is bound to the given object. This method can be safely given as a callback, and even if the this is changed in a method.apply(other_object, arguments), it will be preserved.bindMethod creates a new function object each time you invoke it. So when you're using it with function such as jQuery 'bind'/'unbind' you'll have to make sure to keep a reference to your function.proxyWithState(o:Object)this or self). Doing o getClass() getParent() proxyWithState(o) is the equivalent of creating a super keyword where you can invoke methods from the parent.Step 1: Create a new class
var Shape = Extend.Class(
name:"Shape",
initialize:function(){
this.points = [];
}
methods:{
addPoint:function(p){
this.points.push(p);
}
getPoints:function(){
return this.points;
}
}
});Step 2: Create an instance of your class, and do stuff
my_shape = new Shape(); my_shape.addPoint([0,0]); my_shape.addPoint([1,0]); console.log(my_shape.getPoints().toSource());
Step 3: Create a subclass
var Rectangle = Extend.Class(
name:"Rectangle",
parent:Shape,
initialize:function(){
this.points = [];
}
methods:{
addPoint:function(p){
this.points.push(p);
}
getPoints:function(){
return this.points;
}
}
});Using callbacks with jQuery
var MyWidget = Extend.Class({
name:"MyWidget",
methods:{
onClick:function(target){
$(target).css({background:yello});
}
})
var w = new MyWidget()
$("#my-widget").click( w.getCallback("onClick") )