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": {