finalized mixout(..) api...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2020-05-06 19:27:34 +03:00
parent 58461b949a
commit 87414a8edb
3 changed files with 42 additions and 12 deletions

View File

@ -511,9 +511,16 @@ objects themselves, making them fully reusable.
### `mixout(..)`
Remove objects out of a prototype chain
Remove the first occurrence of each object out of a prototype chain
```
mixout(<base>, <object>, ..)
mixout(<base>, 'first', <object>, ..)
-> <base>
```
Remove all occurrences of each object out of a prototype chain
```
mixout(<base>, 'all', <object>, ..)
-> <base>
```

View File

@ -284,37 +284,60 @@ function(root, ...objects){
// Mix-out sets of methods/props/attrs out of an object prototype chain...
//
// Mix-out first occurrence of each matching object...
// mixout(root, object, ..)
// mixout(root, 'first', object, ..)
// -> root
//
// This is the opposite to mixin(..)
// Mix-out all occurrences of each matching object...
// mixout(root, 'all', object, ..)
// -> root
//
// XXX Q: should this drop all occurences (current) or just the first???
// XXX revise...
//
// This will match an object to a mixin iff:
// - if they are identical or
// - attr count is the same and,
// - attr names are the same and,
// - attr values are identical.
//
// NOTE: this is the opposite to mixin(..)
var mixout =
module.mixout =
function(root, ...objects){
var match = function(root, obj){
var all = objects[0] == 'all' ?
!!objects.shift()
: objects[0] == 'first' ?
!objects.shift()
// default...
: false
var _match = function(root, obj){
// identity...
if(root === obj){
return true }
// attr count...
if(Object.keys(root).length != Object.keys(obj).length){
return false }
// names and values...
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 _drop = function(obj){
var cur = root
while(cur.__proto__ != null){
match(cur.__proto__, obj)
var found = false
while(cur.__proto__ != null
// continue iff ...
&& (all || !found)){
found = _match(cur.__proto__, obj)
found
&& (cur.__proto__ = cur.__proto__.__proto__)
cur = cur.__proto__ }
return root }
cur = cur.__proto__ } }
// do the work...
objects.map(drop)
objects.map(_drop)
return root }

View File

@ -1,6 +1,6 @@
{
"name": "ig-object",
"version": "3.1.0",
"version": "3.2.0",
"description": "",
"main": "object.js",
"scripts": {