Created
December 22, 2011 05:10
-
-
Save draeton/1508995 to your computer and use it in GitHub Desktop.
Playing with classes and inheritance
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* This has essentially turned into Resig's Simple JavaScript Inheritance | |
* with some minor modifications for class names and use strict, | |
* and getters ans setters | |
* http://ejohn.org/blog/simple-javascript-inheritance/ | |
* http://ejohn.org/blog/javascript-getters-and-setters/ | |
*/ | |
(function (window) { | |
"use strict"; | |
// function test | |
var _fnTest = /xyz/.test(function(xyz){}) ? /\b_super\b/ : /.*/; | |
// no operation | |
var _noop = function () {}; | |
// super methods | |
var _makeSuper = function (name, method, proto) { | |
return function () { | |
var tmp = this._super; | |
this._super = proto[name] || _noop; | |
var ret = method.apply(this, arguments); | |
this._super = tmp; | |
return ret; | |
}; | |
}; | |
// the Base constructor for all classes | |
var Base = window.Base = function Base () {}; | |
Base.extend = function (name, settings) { | |
var props = settings || {}; | |
// prototypical inheritance | |
Base._extending = true; | |
var proto = new this(); | |
Base._extending = false; | |
// add properties to prototype | |
var i, g, s; | |
for (i in props) { | |
if (props.hasOwnProperty(i)) { | |
if (typeof props[i] === "function" && _fnTest.test(props[i])) { | |
proto[i] = _makeSuper(i, props[i], this.prototype); | |
} else { | |
g = props.__lookupGetter__(i); | |
s = props.__lookupSetter__(i); | |
if (g || s) { | |
if (g) proto.__defineGetter__(i, g); | |
if (s) proto.__defineSetter__(i, s); | |
} else { | |
proto[i] = props[i]; | |
} | |
} | |
} | |
} | |
// constructor | |
var Class = function Class () { | |
if (!Base._extending && this.initialize) { | |
this.initialize.apply(this, arguments); | |
} | |
}; | |
// add extensibility | |
Class.extend = Base.extend; | |
// return constructor | |
Class.prototype = proto; | |
Class.prototype._class = name; | |
Class.prototype.constructor = Class; | |
return Class; | |
}; | |
})(this); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function (window) { | |
"use strict"; | |
var Base = window.Base; | |
var Person = Base.extend("Person", { | |
initialize: function (name) { | |
this.name = name; | |
this.points = 100; | |
this.alive = true; | |
}, | |
speak: function (text) { | |
console.log(text + " I am a " + this._class + "!"); | |
}, | |
damage: function (points) { | |
this.points += points; | |
if (this.points <= 0) { | |
this.die(); | |
} | |
}, | |
die: function () { | |
this.alive = false; | |
this.points = 0; | |
console.log(this.name + ", " + this + ", is dead."); | |
}, | |
toPrimitive: function () { | |
return this._class; | |
}, | |
toString: function () { | |
return this.toPrimitive(); | |
}, | |
valueOf: function () { | |
return this.toPrimitive(); | |
} | |
}); | |
var Ninja = Person.extend("Ninja", { | |
initialize: function (name) { | |
this._super(name); | |
this.points += 20; | |
}, | |
chop: function (person) { | |
person.damage(-25); | |
} | |
}); | |
var Samurai = Ninja.extend("Samurai", { | |
initialize: function (name) { | |
this._super(name); | |
this.points += 50; | |
}, | |
slice: function (person) { | |
person.damage(-50); | |
} | |
}); | |
var matthew = new Samurai("Matthew"); | |
var michael = new Ninja("Michael"); | |
console.log(matthew, michael); | |
})(this); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment