Skip to content

Instantly share code, notes, and snippets.

@angus-c
Created May 25, 2011 01:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save angus-c/990159 to your computer and use it in GitHub Desktop.
Save angus-c/990159 to your computer and use it in GitHub Desktop.
a fresh approach to mixins
//generic circle functions
var asCircle = function() {
this.area = function() {
return Math.PI * this.radius * this.radius;
}
this.grow = function() {
this.radius++;
}
this.shrink = function() {
this.radius--;
}
return this;
}
//most simple case: applying to object literal
var circle1 = asCircle.call({radius:3});
console.log(circle1.area());
//we can also apply to constructors
var Circle = function(radius) {
this.radius = radius;
}
asCircle.call(Circle.prototype);
var circle1 = new Circle(5);
console.log(circle1.area());
//here's an object for button functions
var asButton = function() {
this.hover = function(bool) {
bool ? mylib.appendClass('hover') : mylib.removeClass('hover');
}
this.press = function(bool) {
bool ? mylib.appendClass('pressed') : mylib.removeClass('pressed');
}
this.fire = function() {
this.action();
}
return this;
}
//mix these two components to make round button
var RoundButton = function(radius, label) {
this.radius = radius;
this.label = label;
}
asButton.call(RoundButton.prototype);
asCircle.call(RoundButton.prototype);
var button1 = new RoundButton(4, 'yes!', function() {console.log('you said yes!')});
button1.fire(); //'you said yes!'
//make rectangle and oval descriptors
var asRectangle = function() {
this.area = function() {
return this.length * this.width;
}
this.grow = function() {
this.length++, this.width++;
}
this.shrink = function() {
this.length--, this.width--;
}
return this;
}
var asOval = function() {
this.area = function() {
return Math.PI * this.longRadius * this.shortRadius;
}
this.ratio = function() {
return this.longRadius/this.shortRadius;
}
this.grow = function() {
this.shortRadius = this.shortRadius + (1/this.ratio());
this.longRadius++;
}
this.shrink = function() {
this.shortRadius = this.shortRadius - (1/this.ratio());
this.longRadius--;
}
return this;
}
//make oval button
var OvalButton = function(longRadius, shortRadius, label, action) {
this.longRadius = longRadius;
this.shortRadius = shortRadius;
this.label = label;
this.action = action;
}
asButton.call(OvalButton.prototype);
asOval.call(OvalButton.prototype);
var button3 = new OvalButton(3, 2, 'send', function() {console.log('message sent')});
console.log(button3.area());
button3.grow();
console.log(button3.area());
button3.fire();
//an example of parameterized mixin (not possible with traditional mixin method)
var asButton = function(options) {
var hoverClass = options && options.hoverClass || 'hover';
var pressedClass = options && options.pressedClass || 'pressed';
this.hover = function(bool) {
bool ? mylib.appendClass(hoverClass) : mylib.removeClass(hoverClass);
}
this.press = function(bool) {
bool ? mylib.appendClass(pressedClass) : mylib.removeClass(pressedClass);
}
this.fire = function() {
this.action();
}
return this;
}
var RectangularButton = function(height, width, label, action) {
this.height = height;
this.width = width;
this.label = label;
this.action = action;
}
asButton.call(RectangularButton.prototype, {pressedClass: 'down'});
asRectangle.call(RectangularButton.prototype);
var button4 = new RectangularButton(5, 7, 'save', function() {console.log('saved')});
button4.hover(true);
button4.press(true);
@orald
Copy link

orald commented Oct 12, 2012

Angus,
I think the RoundButton function is missing 'action' argument (Line 44). It should be,
var RoundButton = function(radius, label, action) {
this.radius = radius;
this.label = label;
this.action = action;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment