Created
September 19, 2016 14:31
-
-
Save petsel/03b42abf5340a973687dc1026d8154d8 to your computer and use it in GitHub Desktop.
A generic approach of a possible static `Object.compare` implementation.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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