Last active
August 29, 2015 14:20
-
-
Save sagiavinash/d206735d31b47b7da96d to your computer and use it in GitHub Desktop.
Check if two values are literally equal
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 literallyEqual(value1, value2) { | |
var _fn = literallyEqual, | |
result = 1; | |
_fn.propLength = {}; | |
// getLength method is used to get simplify equality condition from (a subsetOf b && b subsetOf a) to (a subsetOf b && a.length = b.length). | |
_fn.getLength = function (object) { | |
if(Object.hasOwnProperty("keys")) return Object.keys(object).length; | |
// fallback for Object.keys. | |
var _len = 0, _key; | |
for (_key in object) { _len++; } | |
return _len; | |
}; | |
// get the most specific built-in javascript class of the object. | |
_fn.getClass = function (value) { | |
return Object.prototype.toString.call(value).split(" ")[1].split("]")[0]; | |
}; | |
// check equality using (a == b) for pure primitive values and (a == b && a.length = b.length) for primitive values in object form. | |
_fn.primitiveEqual = function (pValue1, pValue2, isObjLabels) { | |
var status = (_fn.isObj(pValue1) + _fn.isObj(pValue2) === 0) || (_fn.propLength[isObjLabels[0]] === _fn.propLength[isObjLabels[1]]); | |
// support equality for number of any base and notation(3000 === 3e3). | |
return (pValue2 && status) ? (pValue1.toString() === pValue2.toString() ? 1 : 0) : 0; | |
}; | |
// check if value is not a pure primitive value. | |
_fn.isObj = function (value) { | |
return (value instanceof Object); | |
}; | |
_fn.propLength.value1 = _fn.isObj(value1) ? _fn.getLength(value1) : 0; | |
_fn.propLength.value2 = _fn.isObj(value2) ? _fn.getLength(value2) : 0; | |
if (_fn.isObj(value1) || _fn.isObj(value2)) { | |
// check if class is not a pure or simple reference type. | |
if (["Object", "Array"].indexOf(_fn.getClass(value1)) === -1) { | |
result *= _fn.primitiveEqual(value1, value2, ["value1", "value2"]); | |
} else { | |
result *= (_fn.propLength.value1 === _fn.propLength.value2) ? 1 : 0; | |
} | |
(function () { | |
var _key, _v1, _v2; | |
for (_key in value1) { | |
_v1 = value1[_key]; | |
_v2 = value2[_key]; | |
if (_fn.isObj(_v1) || _fn.isObj(_v2)) { | |
_fn.propLength._v1 = _fn.isObj(_v1) ? _fn.getLength(_v1) : 0; | |
_fn.propLength._v2 = _fn.isObj(_v1) ? _fn.getLength(_v1) : 0; | |
if (["Object", "Array"].indexOf(_fn.getClass(_v1)) === -1) { | |
// check if two primitive values are equal superficially. | |
result *= _fn.primitiveEqual(_v1, _v2, ["_v1", "_v2"]); | |
} | |
// recursive call to check the inner objects or declared properties on primitive object types match for both the compared values. | |
result *= _fn(_v1, _v2); | |
} else { | |
// check equality for pure primitive type values inside object | |
result *= _fn.primitiveEqual(_v1, _v2, ["_v1", "_v2"]); | |
} | |
} | |
}()); | |
} else { | |
// check equality for pure primitive types | |
result *= _fn.primitiveEqual(value1, value2, ["value1", "value2"]); | |
} | |
return !!result; | |
} | |
/* make this file both AMD and non-AMD compatibile library */ | |
if (typeof define === "function" && define.amd) { | |
define("literallyEqual", [], function () { | |
return literallyEqual; | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment