Created
March 10, 2015 00:50
-
-
Save mrunderhill89/b98b01aeaf8bcd0c0d23 to your computer and use it in GitHub Desktop.
An implementation of mixin to go along with my Interface class.
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
define(['underscore', 'interface'], function(_, Interface){ | |
mixin_interface = new Interface({ | |
proto_methods:["mix"], | |
static_methods:["proto_mix"] | |
}); | |
var Mixin = mixin_interface.implement({ | |
fields:{ | |
default_mixins:[], | |
default_property:"mixin" | |
}, | |
methods: { | |
//Mixes the given functions from this mixin into another object directly. | |
mix: function(target, functions){ | |
functions || (functions=this.default_mixins); | |
var is_array = _.isArray(functions); | |
_.defaults(target, | |
_.reduce(functions, function(methods, object_f, mixin_f){ | |
if (is_array){mixin_f = object_f}; | |
methods[object_f] = function(){ | |
return this[mixin_f].apply(this,arguments); | |
}.bind(this); | |
return methods; | |
}.bind(this),{}) | |
); | |
return this; | |
} | |
}, | |
static: { | |
//Mixes the given functions into an object prototype. | |
//The "property" field locates a mixin instance within the target object. | |
proto_mix:function(prototype, property, functions){ | |
property || (property = this.default_property); | |
functions || (functions=this.default_mixins); | |
var is_array = _.isArray(functions); | |
return _.defaults(prototype, | |
_.reduce(functions, function(methods, object_f, mixin_f){ | |
if (is_array){mixin_f = object_f}; | |
methods[object_f] = function(){ | |
var instance = this[property]; | |
return instance[mixin_f].apply(instance,arguments); | |
}; | |
return methods; | |
},{}) | |
); | |
}, | |
/* | |
Implements a new class that inherits from Mixin. | |
Yeah, I know the whole point of using Mixins is to move away from | |
implementation inheritance, but this is the fastest way to make new | |
mixins, so I'll concede on this point. All the parameters from Instance.implement | |
are supported, as well as the following new ones: | |
-default_mixins: sets up default mixin functions. | |
-default_property: sets up default property for prototype mixing. | |
-interface: lets you select an interface for the finished object. | |
The interface is automatically appended onto Mixin.interface. | |
*/ | |
implement: function(params){ | |
params = params || {}; | |
return mixin_interface.implement( | |
_.extend(params,{ | |
methods: _.extend(params.methods, {mix: this.prototype.mix}), | |
static: _.extend(params.static, {proto_mix: this.proto_mix}) | |
}) | |
).implements(params.interface); | |
}, | |
} | |
}); | |
return Mixin; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment