How can I implement traits in javascript ?
So do i need a whole library to use traits ? javascript is prototype basewd language right ? It should have the capability to implement traits
Tinku
2009-12-30 06:52:58
"javascript is prototype basewd language right ?" Sort of. More info can be found here: http://www.lshift.net/blog/2006/07/24/subclassing-in-javascript-part-1 Also useful: http://javascript.crockford.com/inheritance.html
Andy West
2009-12-30 07:20:22
In the http://www.lshift.net/blog/2006/07/24/subclassing-in-javascript-part-1 link, the author starts with valid information. Later it is clear he doesn't know much about javascript.
trinithis
2009-12-30 17:58:26
As for the Crockford link, just be wary of his uber method. It doesn't work exactly like super does in most other languages, and you may end up with hard to find bugs if methods end up using a series of mutual recursion.
trinithis
2009-12-30 18:05:45
+2
A:
function Trait (methods) {
this.traits = [methods];
};
Trait.prototype = {
constructor: Trait
, uses: function (trait) {
this.traits = this.traits.concat (trait.traits);
return this;
}
, useBy: function (obj) {
for (var i = 0; i < this.traits.length; ++i) {
var methods = this.traits [i];
for (var prop in methods) {
if (methods.hasOwnProperty (prop)) {
obj [prop] = obj [prop] || methods [prop];
}
}
}
}
};
Trait.unimplemented = function (obj, traitName) {
if (obj === undefined || traitName === undefined) {
throw new Error ("Unimplemented trait property.");
}
throw new Error (traitName + " is not implemented for " + obj);
};
Example:
var TEq = new Trait ({
equalTo: function (x) {
Trait.unimplemented (this, "equalTo");
}
, notEqualTo: function (x) {
return !this.equalTo (x);
}
});
var TOrd = new Trait ({
lessThan: function (x) {
Trait.unimplemented (this, "lessThan");
}
, greaterThan: function (x) {
return !this.lessThanOrEqualTo (x);
}
, lessThanOrEqualTo: function (x) {
return this.lessThan (x) || this.equalTo (x);
}
, greaterThanOrEqualTo: function (x) {
return !this.lessThan (x);
}
}).uses (TEq);
function Rational (numerator, denominator) {
if (denominator < 0) {
numerator *= -1;
denominator *= -1;
}
this.numerator = numerator;
this.denominator = denominator;
}
Rational.prototype = {
constructor: Rational
, equalTo: function (q) {
return this.numerator * q.numerator === this.denominator * q.denominator;
}
, lessThan: function (q) {
return this.numerator * q.denominator < q.numerator * this.denominator;
}
};
TOrd.useBy (Rational.prototype);
var x = new Rational (1, 5);
var y = new Rational (1, 2);
[x.notEqualTo (y), x.lessThan (y)]; // [true, true]
trinithis
2009-12-30 08:18:49
Moved the TOrd.useBy outside of the Rational constructor to act on the prototype instead.
trinithis
2009-12-31 07:40:15