added mixout(..)...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2020-05-06 05:30:11 +03:00
parent 604dda2381
commit f308cbc756
2 changed files with 89 additions and 6 deletions

View File

@ -105,6 +105,7 @@ class L extends Array {
- [Inheritance](#inheritance)
- [Callable instances](#callable-instances)
- [Advanced usage](#advanced-usage)
- [Mix-ins](#mix-ins)
- [Low level constructor](#low-level-constructor)
- [Extending the constructor](#extending-the-constructor)
- [Inheriting from native constructor objects](#inheriting-from-native-constructor-objects)
@ -242,6 +243,40 @@ user's responsibility to call `.__call__(..)` method.
(this may change in the future)
### Mix-ins
Prototype-based mixin...
```javascript
var utilityMixin = {
utility: function(){
// ...
},
}
var Base = object.Constructor('Base')
// mixin directly into the instance...
var m = object.mixin(Base(), utilityMixin)
```
`.mixin(..)` will copy the contents of `utilityMixin` into the prototype
chain between `m` and `m.__proto__`.
Constructor-based mixin...
```javascript
var UtilityMixin = function(parent){
return object.Constructor(parent.name + '+utils', parent, utilityMixin) }
var Mixed = object.Constructor('Mixed', UtilityMixin(Base), {
// ...
})
var m = Mixed()
```
## Advanced usage

View File

@ -206,8 +206,8 @@ function(proto, name){
// Find the next parent method and call it...
//
// parentCall(proto, name, this, ...)
// parentCall(meth, this, ...)
// parentCall(proto, name, this, ..)
// parentCall(meth, this, ..)
// -> res
// -> undefined
//
@ -260,7 +260,7 @@ function(root, ...objects){
// Mix sets of methods/props/attrs into an object as prototypes...
//
// mixin(root, object, ...)
// mixin(root, object, ..)
// -> root
//
//
@ -268,14 +268,62 @@ function(root, ...objects){
// mixinFlat(..) the method set into this object leaving the
// original objects intact.
//
// root <-- object1_copy <-- .. <-- objectN_copy
// root <-- object1_copy <-- .. <-- objectN_copy <- root.__proto__
//
//
// NOTE: this will only mix in non-empty objects...
//
// XXX BUG: this is wrong...
// var m = { m: function(){ console.log('!!!') } }
// var a = object.Constructor('A', Array, {})()
// var aa = object.mixin(a, m)
// aa === a // -> false
var mixin =
module.mixin =
function(root, ...objects){
return objects
root.__proto__ = objects
.reduce(function(res, cur){
return module.mixinFlat(Object.create(res), cur) }, root) }
return Object.keys(cur).length > 0 ?
module.mixinFlat(Object.create(res), cur)
: res }, root.__proto__)
return root }
// Mix-out sets of methods/props/attrs out of an object prototype chain...
//
// mixout(root, object, ..)
// -> root
//
// This is the opposite to mixin(..)
//
// XXX Q: should this drop all occurences (current) or just the first???
// XXX revise...
var mixout =
module.mixout =
function(root, ...objects){
var match = function(root, obj){
if(root === obj){
return true }
if(Object.keys(root).length != Object.keys(obj).length){
return false }
var e = Object.entries(obj)
while(e.length > 0){
var [k, v] = e.pop()
if(!root.hasOwnProperty(k) || root[k] !== v){
return false } }
return true }
var drop = function(obj){
var cur = root
while(cur.__proto__ != null){
match(cur.__proto__, obj)
&& (cur.__proto__ = cur.__proto__.__proto__)
cur = cur.__proto__ }
return root }
// do the work...
objects.map(drop)
return root }