diff --git a/README.md b/README.md
index 83b6f70..3d2c791 100755
--- a/README.md
+++ b/README.md
@@ -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( , , ..)
+mixout( , 'first', , ..)
+ ->
+```
+
+Remove all occurrences of each object out of a prototype chain
+```
+mixout( , 'all', , ..)
->
```
diff --git a/object.js b/object.js
index 3f96d67..c536ea6 100755
--- a/object.js
+++ b/object.js
@@ -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 }
diff --git a/package.json b/package.json
index d4cb8d3..0574a66 100755
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "ig-object",
- "version": "3.1.0",
+ "version": "3.2.0",
"description": "",
"main": "object.js",
"scripts": {