Created
October 5, 2015 13:30
-
-
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].
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 (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