Skip to content

Instantly share code, notes, and snippets.

@jblanche
Created March 8, 2012 16:00
Show Gist options
  • Save jblanche/2001684 to your computer and use it in GitHub Desktop.
Save jblanche/2001684 to your computer and use it in GitHub Desktop.
An Example of usage of my proto.js fork
/*
This is a test aiming at creating a simple inheritance + mixin capable JS library
using Object.create awesome possibilities.
It's using a single library (https://raw.github.com/jblanche/proto-js/master/Proto.js) that is only 609 characters minified, and 310b gzipped.
It is heavily based on the original Proto.JS library (https://github.com/rauschma/proto-js).
Simply adding to it an easy way to add mixins to our "Classes".
*/
// This is a Mixin / Module, it can be included by any "Class", whatever the class role.
// It's a plain and simple JS litteral object.
var Comparable = {
// The Only thing this mixin needs is a "compare" method in the Class that includes it.
isGreaterThan : function(other){
return this.compare(other) === 1;
},
isEqualTo : function(other){
return this.compare(other) === 0;
},
isLowerThan : function(other){
return this.compare(other) === -1;
},
isLowerOrEqualTo : function(other){
return this.compare(other) <= 0;
},
isGreaterOrEqualTo : function(other){
return this.compare(other) >= 0;
},
between: function(min, max){
if(this.compare(min) < 0 || this.compare(max) >0){
return false;
}
return true ;
}
};
// This is a Simple Particle class with position (x,y) and a radius.
// Proto.Extend takes a simple litteral object as its only parameter
// Every propertie or method defined in this object will be available on object instances.
var Particle = Proto.extend({
// The constructor method is the initializer, it is called automatically when creating an instance
constructor: function(options){
//Defining main properties
this.x = options.x || 0 ;
this.y = options.y || 0 ;
this.radius = options.radius || 1 ;
},
// this is the Compare method our Comparable mixin will use.
// We are defining that particles are compared based on their radius.
compare: function(other){
if(this.radius > other.radius) return 1 ;
else if(this.radius === other.radius) return 0 ;
else return -1 ;
},
describe: function(){
return "I'm in "+this.x+ " : " + this.y+" , radius: "+this.radius;
}
});
// include Comparable mixin
extend(Particle, Comparable);
// The ColorParticle is a "SubClass" of Particle "Particle.extend({})"
// No need to redefined "compare" here, if compare is called on a ColorParticle "instance"
// the Particle "compare" method is in the prototype chain and will be called.
var ColorParticle = Particle.extend({
constructor: function(options){
ColorParticle.super.constructor.call(this, options);
this.color = options.color || "#FFF" ;
},
describe: function(){
return ColorParticle.super.describe.call(this) + " and I'm "+this.color;
}
});
// This is a Person class, not a lot to share with particles...
// But I want People to be comparable too, so lets include comparable there too.
var Person = Proto.extend({
constructor: function (name, height) {
this.name = name;
this.height = height ;
},
// Persons are compared based on their height (Yes I know, this is dumb).
compare: function(other){
if(this.height > other.height) return 1 ;
else if(this.height === other.height) return 0 ;
else return -1 ;
},
describe: function() {
return "Person called "+this.name;
}
});
// include Comparable mixin
extend(Person, Comparable);
// This is the Employee class, SubClass of the Person one.
// Employee redefines the Person compare method to use salary instead of height.
var Employee = Person.extend({
constructor: function (name, height, salary) {
Employee.super.constructor.call(this, name, height);
this.salary = salary || 0;
},
// Employees are compared based on their salary (Yes I know, this is dumber).
compare: function(other){
if(this.salary > other.salary) return 1 ;
else if(this.salary === other.salary) return 0 ;
else return -1 ;
},
describe: function () {
return Employee.super.describe.call(this)+" (earns $"+this.salary+" a month)";
}
});
// Let's create a few particles and compare them
var particule1 = Particle.new({x:2, y:4, radius:5});
var particule2 = ColorParticle.new({x:5, y:8, radius:10, color: '#CCC'});
var particule3 = ColorParticle.new({x:12, y:4, radius:7, color: '#F0F'});
console.log("particule2.isEqualTo(particule1) : ", particule2.isEqualTo(particule1)); // false
console.log("particule2.describe() : ", particule2.describe()); // I'm in 5 : 8 , radius: 10 and I'm #CCC
console.log("ColorParticle.isPrototypeOf(particule2) : ", ColorParticle.isPrototypeOf(particule2)); // true
console.log("ColorParticle.isPrototypeOf(particule1) : ", ColorParticle.isPrototypeOf(particule1)); // false
console.log("particule3.between(particule1, particule2) : ", particule3.between(particule1, particule2)); // true
// What about persons
var person1 = Person.new('Alice', 164);
var person2 = Person.new('Bob', 180);
console.log("person2.isLowerOrEqualTo(person1)", person2.isLowerOrEqualTo(person1)); // false
console.log("person2.describe()", person2.describe()); //Person called Bob
// Or employees
var employee1 = Employee.new('John', 174, 2000);
var employee2 = Employee.new('Jane', 168, 3000);
var employee3 = Employee.new('Jill', 170, 4000);
console.log("employee2.isGreaterThan(employee1)", employee2.isGreaterThan(employee1)); // true
console.log("employee2.describe()", employee2.describe()); // Person called Jane (earns $3000 a month)
console.log("employee3.between(employee1, employee2)", employee3.between(employee1, employee2)); // false
// I can even apply some behavior to a single instance
var Teenable = {
describe: function(){return 'LOL XPTDR';}
}
extend(employee3, Teenable);
console.log("employee3.describe()", employee3.describe()); // LOL XPTDR
// other instances are steal clean
console.log("employee2.describe()", employee2.describe()); // Person called Jane (earns $3000 a month)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment