Created
December 17, 2014 11:21
-
-
Save tjmcewan/c293a4f9e0025f00a528 to your computer and use it in GitHub Desktop.
javascript table of equality
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
<html><head></head><body></body> | |
<script type="text/javascript"> | |
// italics for objects | |
(function (values) { | |
function toString(x) { | |
var v = x; | |
v = (v || v === "") ? JSON.stringify(v) : String(v); | |
if (typeof x === 'object') v = v.italics(); | |
return v; | |
} | |
function describe (i,j) { | |
var v1 = values[i], | |
v2 = values[j]; | |
if (i === j) { | |
if (Number.isNaN(v1)) { | |
return "NaN !== NaN by definition"; | |
} else { | |
return "any value is equal to itself"; | |
} | |
} | |
var a1,a2,s1,s2,cf; | |
if (v1 == null | |
|| v2 == null) { | |
return "undefined only equals to null (except itself)"; | |
} else if ( | |
typeof v1 === 'object' | |
&& typeof v2 === 'object') { | |
return "objects are compared by reference"; | |
}else if ( | |
typeof v1 === 'number' | |
|| typeof v1 === 'boolean' | |
|| typeof v2 === 'number' | |
|| typeof v2 === 'boolean') { | |
cf = Number; | |
} else { | |
cf = String; | |
} | |
function toPrimitive (v) { | |
var s = '', p; | |
if (v.constructor === cf) return "no conversion required"; | |
if (typeof v === 'object') { | |
p = v.valueOf(); | |
s += "valueOf: " + toString(p); | |
if (typeof p === 'object') { | |
s += " - non-primitive\n"; | |
p = v.toString(); | |
s += "toString: " + toString(p); | |
if (typeof p === 'object') { | |
s += " - non-primitive\n"; | |
s += "Couldn't convert to primitive!\n"; | |
} else { | |
s += "\n"; | |
} | |
} else { | |
s += "\n"; | |
} | |
s += "ToPrimitive(" + toString(v) + ") -> " + toString(p) + "\n"; | |
} else { | |
p = v; | |
} | |
return s + cf.name + "(" + toString(p) + ") -> " + toString(cf(v)); | |
} | |
a1 = cf(v1); s1 = toString(a1); | |
a2 = cf(v2); s2 = toString(a2); | |
return [ | |
cf === Number ? "Having numbers or booleans" : "Having strings", | |
"<u>arg#1</u>: " + toString(v1), | |
toPrimitive(v1), | |
"<u>arg#2</u>: " + toString(v2), | |
toPrimitive(v2), | |
s1 + ' ' + (a1 === a2 ? '===' : '!==') + ' ' + s2 | |
].join("\n"); | |
} | |
var h = | |
"<style>" + | |
"opaque{opacity:0.5}" + | |
"table{font-family:sans-serif}" + | |
"td{max-width:22px;min-width:22px;height:22px;overflow:hidden;border:1px solid silver}" + | |
".w{min-width:99px;max-width:99px}" + | |
".v{min-width:40px;max-width:40px}" + | |
".c{cursor:pointer;border:1px solid rgba(0, 0, 0, 0.3);border-radius:3px}" + | |
".y{background:#2e2}.n{background:#f99}.q{background:#bbb}.r{background:#fc8}"+ | |
".t{text-align:center}"+ | |
"#s{white-space:pre;font-family:monospace;min-height:5em}"+ | |
"</style>"; | |
h += "<table>"; | |
h += "<tr class='t'><td><i>falsy?</i></td>"; | |
h += values.map(function (v) { | |
return "<td>" + toString(v) + "</td>"; | |
}).join(''); | |
h += "<td class='v'>bool</td><td class='v'>num</td><td class='w'>string</td><td class='w'>valueOf</td><td class='w'>toString</td>"; | |
h += "</tr>"; | |
h += values.map(function (vi, i) { | |
return ( | |
"<tr>" + | |
"<td class='w " + (vi ? 'y' : 'n') + "'>" + toString(vi) + "</td>" + | |
values.map(function (vj, j) { | |
var c; | |
if (i == j) { | |
c = (Number.isNaN(vj) ? 'n' : 'q'); | |
} else { | |
if (vi && vj | |
&& typeof vi === 'object' | |
&& typeof vj === 'object' | |
&& vi.toString() == vj.toString()) { | |
c = 'r'; | |
} else { | |
c = (vi == vj ? 'y' : 'n'); | |
} | |
} | |
return "<td class='c " + c + "' idx='" + [i,j] + "'></td>"; | |
}).join('') + | |
"<td>" + Boolean(vi) + "</td><td>" + Number(vi) + "</td><td>" + String(vi) + "</td>" + | |
(vi | |
? "<td>" + toString(vi.valueOf()) + "</td><td>\"" + vi.toString() + "\"</td>" | |
: "<td>" + vi + "</td><td>\"" + vi + "\"</td>") + | |
"</tr>" | |
); | |
}).join(''); | |
h += "</table><div id='s'></div>"; | |
document.body.innerHTML = h; | |
var t = document.querySelector('table'), | |
s = document.styleSheets[document.styleSheets.length-1], | |
d = document.getElementById('s'); | |
t.onmousemove = function(event) { | |
var g = event.target; | |
if (!g.classList.contains('c')) return; | |
d.innerHTML = describe.apply(null,g.getAttribute('idx').split(',')); | |
s.cssRules[0].selectorText = [ | |
"tr:nth-child(" + (g.parentNode.rowIndex+1) + ") .c", | |
"td.c:nth-child(" + (g.cellIndex+1) + ")" | |
]; | |
}; | |
}([true, 1, '1', [1], ['1'], false, 0, '0', [0], ['0'], '', [], [[]], '-1', -1, [-1], ['-1'], {}, null, undefined, NaN])); | |
</script></html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment