Skip to content

Instantly share code, notes, and snippets.

@petsel
Created September 19, 2016 14:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save petsel/03b42abf5340a973687dc1026d8154d8 to your computer and use it in GitHub Desktop.
Save petsel/03b42abf5340a973687dc1026d8154d8 to your computer and use it in GitHub Desktop.
A generic approach of a possible static `Object.compare` implementation.
(function (Object) {
var
expose_internal_value = Object.prototype.valueOf,
NULL_VALUE = null,
UNDEFINED_VALUE,
TYPEOF_FUNCTION_TYPE = "function";
function isFunction(type) {
return (
(typeof type == TYPEOF_FUNCTION_TYPE)
&& (typeof type.call == TYPEOF_FUNCTION_TYPE)
&& (typeof type.apply == TYPEOF_FUNCTION_TYPE)
);
}
function baseValueOf(type) {
/**
* Object.prototype.valueOf.call(new String(1)) // "[object String]"
* Object.prototype.valueOf.call(new Number("1")) // "[object Number]"
* //versus
* Object.prototype.valueOf.call(new String(1)).valueOf() // "1" [string] value
* Object.prototype.valueOf.call(new Number("1")).valueOf() // 1 [number] value
*/
return (type == NULL_VALUE) ? type : expose_internal_value.call(type).valueOf();
}
/**
*
* @param typeA
* @param typeB
* @param config {[ customValueOf:Function[, compareValues:Function[, compareTypes:Function ]]]}
* @returns {number(>|===|< 0)|undefined}
*/
function compareTypes(typeA, typeB, config) {
config = config || {};
var
compareTypes = config.compareTypes, // - custom comparator method that directly compares 2 types.
compareValues = config.compareValues, // - custom comparator method that directly compares 2 `valueOf` states each derived from its outer methods 2 types.
valueOf = (isFunction(config.customValueOf) && config.customValueOf) || baseValueOf, // - method that converts a type into its `valueOf` state.
valueA,
valueB;
return (
isFunction(compareTypes)
? compareTypes(typeA, typeB) // @returns {number(>|===|< 0)|undefined}
: (
isFunction(compareValues)
? compareValues(valueOf(typeA), valueOf(typeB)) // @returns {number(>|===|< 0)|undefined}
: (
(((valueA = valueOf(typeA)) > (valueB = valueOf(typeB))) && 1)
|| ((valueA < valueB) && -1)
//|| ((valueA == valueB) ? 0 : UNDEFINED_VALUE)
|| ((valueA === valueB) ? 0 : UNDEFINED_VALUE) // - as for UNDEFINED_VALUE, the 4th possible return value,
// please countercheck with [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort]
// as well as with [http://apidock.com/ruby/Comparable].
)
)
);
}
Object.compare = compareTypes;
return Object;
}(Object));
/*
[http://closure-compiler.appspot.com/home]
- Simple - 413 byte
(function(c){function d(a){return"function"==typeof a&&"function"==typeof a.call&&"function"==typeof a.apply}function k(a){return null==a?a:l.call(a).valueOf()}var l=c.prototype.valueOf;c.compare=function(a,c,b){b=b||{};var g=b.compareTypes,h=b.compareValues;b=d(b.customValueOf)&&b.customValueOf||k;var e,f;return d(g)?g(a,c):d(h)?h(b(a),b(c)):(e=b(a))>(f=b(c))&&1||e<f&&-1||(e===f?0:void 0)};return c})(Object);
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment