Skip to content

Instantly share code, notes, and snippets.

@petsel
Created October 5, 2015 13:30
Show Gist options
  • Select an option

  • Save petsel/cd46d761a10e5bb78b3b to your computer and use it in GitHub Desktop.

Select an option

Save petsel/cd46d761a10e5bb78b3b to your computer and use it in GitHub Desktop.
prototypal object (de)composition methods targeting function based Traits/Mixins working from an [Object] based view as antipode to [Function.call/apply].
(function (Object, Array) {
"use strict";
var
object_prototype = Object.prototype,
isObject = function is_object (type) {
var
typeofType = (type && (typeof type))
;
return !!(typeofType && ((typeofType == "object") || (typeofType == "function")));
},
isFunction = (function (FUNCTION_TYPE) {
return function is_function (type) {
return (
(typeof type == FUNCTION_TYPE)
&& (typeof type.call == FUNCTION_TYPE)
&& (typeof type.apply == FUNCTION_TYPE)
);
};
}(typeof Object)),
array_from = (isFunction(Array.from) && Array.from) || (Array.from = (function array_from (array_prototype_slice) {
return function (listLike) {
return array_prototype_slice.call(listLike);
};
}(Array.prototype.slice))),
object_keys = Object.keys,
withTrait = function with_trait (/*Trait[, arg_01[, arg_02[, ...]]]*/) {
var
type = this,
args = array_from(arguments),
Trait = args.shift()
;
if (isObject(type) && isFunction(Trait)) {
Trait.apply(type, args);
}
return type;
},
withdrawTrait = function withdraw_trait (type, Trait) {
var obj = {};
Trait.call(obj);
object_keys(obj).forEach(function (key) {
delete type[key];
});
//return type;
},
withoutTraits = function without_traits (/*Trait[, Trait_01[, Trait_02[, ...]]]*/) {
var
type = this
;
if (isObject(type)) {
array_from(arguments).forEach(function (Trait/*, idx, list, target*/) {
(isFunction(Trait) && withdrawTrait(type, Trait));
}/*, type*/);
}
return type;
}
;
object_prototype["with"] = withTrait;
object_prototype.without = withoutTraits;
return Object;
}(Object, Array));
/*
[http://closure-compiler.appspot.com/home]
- Simple - 604 byte
(function(c,d){var f=c.prototype,g=function(a){a=a&&typeof a;return!(!a||"object"!=a&&"function"!=a)},e=function(a){return function(b){return typeof b==a&&typeof b.call==a&&typeof b.apply==a}}(typeof c),h=e(d.from)&&d.from||(d.from=function(a){return function(b){return a.call(b)}}(d.prototype.slice)),k=c.keys,l=function(a,b){var c={};b.call(c);k(c).forEach(function(b){delete a[b]})};f["with"]=function(){var a=h(arguments),b=a.shift();g(this)&&e(b)&&b.apply(this,a);return this};f.without=function(){var a=this;g(a)&&h(arguments).forEach(function(b){e(b)&&l(a,b)});return a};return c})(Object,Array);
*/
var MyTrait = (function () {
"use strict";
var behavior = function () {
console.log("behavior :: this", this);
};
var MyTrait = function Functor () {
var
type = this
;
console.log("Functor :: type, arguments", type, arguments);
type.behavior = behavior;
};
return MyTrait;
}());
var MyType = (function () {
"use strict";
var method = function () {
console.log("method :: this", this);
};
var MyType = function Constructor () {
var
type = this,
args = Array.from(arguments)
;
console.log("Constructor :: type, arguments", type, arguments);
type.method = method;
type
.with.apply(type, (args.unshift(Trait) && args))
//.with(Trait_02/*[, arg_01[, arg_02[, ...]]]*/)
//.with(Trait_03/*[, arg_01[, arg_02[, ...]]]*/)
;
};
return MyType;
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment