Skip to content

Instantly share code, notes, and snippets.

@Bluebie
Created September 16, 2011 06:17
Show Gist options
  • Save Bluebie/1221342 to your computer and use it in GitHub Desktop.
Save Bluebie/1221342 to your computer and use it in GitHub Desktop.
Lay - a simple kind of class-ish object constructor kit for modern javascript
// tests lay
var LayTest1 = lay({
constructor: function(g, d) { this.g = d, this.d = g; },
gud: function() { return this.d + 'u' + this.g; },
isGud: function() { return false; }
});
var LayTest2 = lay({
atop: LayTest1.prototype,
constructor: function(f,o,o) { this.foo = 'bats'; return this.atop('constructor', f, 'd'); },
isGud: function() { return (this.gud() == 'gud') && (this.atop('isGud') == false); }
})
var laytest3 = new LayTest2('g', 'o', 'o');
if (!laytest3.isGud()) throw new Error('Lay is broken. It\'s not looking good.');
// lay is Jenna's little utility for getting some friendlier prototype layery inheritance stuff happening
/* use like this:
* var MyThing = lay({
* atop: Thing.prototype,
* constructor: function(word) { this.bar = word; return this.atop('constructor', word); },
* foo: function() { return this.bar; }
* })
* makes a MyThing 'class' which inherits from Thing.
* using this.atop('methodName', arg, arg, arg...) calls a direct ancestor method with current level binding.
*/
var lay = function self(spec) {
var init = (spec.constructor || function() {});
if (!spec.outards) spec.outards = {};
if (spec.atop) jQuery.extend(init.prototype, spec.atop);
jQuery.extend(init.prototype, spec);
jQuery.extend(init, spec.outards)
init.prototype.atop = function() {
if (arguments.length > 0) {
var args = jQuery.makeArray(arguments);
var method = args.shift();
return spec.atop[method].apply(this, args);
} else {
return spec.atop;
}
}
jQuery.extend(init, self.extras);
return init;
}
lay.extras = {
// get methods or add some more
innards: function(bits) {
if (bits) jQuery.extend(this.prototype, bits);
return this.prototype;
},
outards: function(bits) {
jQuery.extend(this.prototype.outards, bits);
jQuery.extend(this, bits);
return this;
}
}
@judofyr
Copy link

judofyr commented Sep 16, 2011

Why do you use extend instead of creating a prototype-chain? if (spec.atop) init.prototype = new spec.atop and use atop: LayTest1.

@Bluebie
Copy link
Author

Bluebie commented Sep 16, 2011

new spec.atop would call the parent's constructor function, which is undesirable, but it could use Object.create I suppose. I'm almost inclined to just say to heck with new, and do a ruby-style thing, but without all this 'prototype' property nonsense.

@Bluebie
Copy link
Author

Bluebie commented Sep 17, 2011

Just as a sidenote - it's undesirable to assign a new object to .prototype, as doing so disables some important speed optimisations in some javascript interpreters (namely V8, maybe others?) - it's much better to use Object.create where possible, and fall back to .prototype assigns where that's unavailable.

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