Skip to content

Instantly share code, notes, and snippets.

@passcod
Last active December 21, 2015 17:29
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save passcod/6340716 to your computer and use it in GitHub Desktop.
Save passcod/6340716 to your computer and use it in GitHub Desktop.
This is really normal prototypal inheritance, and the #extend and #create methods are just there for convenience, not to hide away the magic.
Namespace.extend = (src, obj = {}) ->
if typeof obj.init is 'function'
newObj = obj.init
delete obj.init
else
newObj = ->
newObj.prototype = Object.create src.prototype
newObj.prototype.constructor = newObj
for prop of obj
newObj.prototype[prop] = obj[prop]
props = {}
Object.keys(src).forEach (prop) ->
props[prop] = Object.getOwnPropertyDescriptor(src, prop)
['create', 'extend'].forEach (prop) ->
((func, self) ->
props[func] = Object.getOwnPropertyDescriptor(Namespace, func)
props[func].value = () ->
args = [].slice.call arguments
args.unshift self
Namespace[func].apply(this, args)
)(prop, newObj)
Object.defineProperties(newObj, props)
return newObj
Namespace.create = (src, obj, init) ->
newObj = src.extend obj
new newObj(init)
Namespace.Object = Namespace.extend ->
Actor = Namespace.Object.extend
act: ->
# and he stepeth and speaketh
canSpeak: true
MuteActor = Actor.extend
canSpeak: false
Actor.act #=> undefined
(new Actor).act #=> function
(new Actor).canSpeak #=> true
(new MuteActor).canSpeak #=> true
(new Actor) instanceof Namespace.Object #=> true
(new MuteActor) instanceof Actor #=> true
(new MuteActor) instanceof Namespace.Object #=> true
(new Actor) instanceof MuteActor #=> false
CustomConstructor = Namespace.Object.extend
init: ->
console.log 'Yippy!'
new CustomConstructor #$> 'Yippy!'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment