Skip to content

Instantly share code, notes, and snippets.

@sagiavinash
Last active August 29, 2015 14:20
Show Gist options
  • Save sagiavinash/d206735d31b47b7da96d to your computer and use it in GitHub Desktop.
Save sagiavinash/d206735d31b47b7da96d to your computer and use it in GitHub Desktop.
Check if two values are literally equal
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