Не заставляйте (не)равенства в JavaScript выглядеть хуже, чем они есть

Время от времени я встречаю публикации, где рассказывается о том, какие из значений оператора == эквивалентны (как, например, здесь). Часто при этом оговаривается, что приведённые в таблице данные не очень хорошо организованы.

Я согласен, такие таблицы нужны, чтобы лучше ориентироваться в несовершенствах оператора… вот только несовершенства в организации данных в самих таких таблицах, на мой взгляд ещё больше усложняют ситуацию. Вот, к примеру, таблица из ссылки, приведённой выше:

Кошмар, товарищи!.. Как по мне, так здесь бóльший беспорядок в очерёдности строк/столбцов.

Сгруппировав их по наличию пересечений мы получим более внятную картину:

Так легче ориентироваться, не правда ли? А ещё такая организация таблицы позволяет сразу увидеть несовершенства ==.

Код

Ниже приведён код, который я использовал для создания моей версии этой таблицы. Он доступен на jsfiddle.

HTML

<canvas id="drawCanvas" width="500" height="500" /> 

JavaScript

var cmp = function(v1, v2) { return v1 == v2; }; var vals = [     ["false", function() { return false; }],      ["0", function() { return 0; }],     ['""', function() { return ""; }],     ["[[]]", function() { return [[]]; }],      ["[]", function() { return []; }],      ['"0"', function() { return "0"; }],      ["[0]", function() { return [0]; }],      ["[1]", function() { return [1]; }],     ['"1"', function() { return "1"; }],     ["1",function() { return  1; }],     ["true", function() { return true; }],     ["-1", function() { return -1; }],     ['"-1"', function() { return "-1"; }],     ["null", function() { return null; }],     ["undefined", function() { return undefined; }],     ["Infinity", function() { return Infinity; }],     ["-Infinity", function() { return -Infinity; }],     ['"false"', function() { return "false"; }],     ['"true"', function() { return "true"; }],     ["{}", function() { return {}; }],      ["NaN", function() { return NaN; }] ];  var canvas = document.getElementById("drawCanvas"); var ctx = canvas.getContext("2d"); var n = vals.length; var r = 20; // diameter of grid squares var p = 60; // padding space for labels  // color grid cells for (var i = 0; i < n; i++) {     var v1 = vals[i][1]();     for (var j = 0; j < n; j++) {         var v2 = vals[j][1]();         var eq = cmp(v1, v2);         ctx.fillStyle = eq ? "orange" : "white";         ctx.fillRect(p+i*r,p+j*r,r,r);     } }  // draw labels ctx.fillStyle = "black"; var f = 12; ctx.font = f + "px Helvetica"; for (var i = 0; i < n; i++) {     var s = vals[i][0];     var w = ctx.measureText(s).width;     ctx.save();     ctx.translate(p+i*r+r/2-f*0.4,p-w-2);     ctx.rotate(3.14159/2);     ctx.fillText(s, 0, 0);     ctx.restore(); } for (var i = 0; i < n; i++) {     var s = vals[i][0];     var w = ctx.measureText(s).width;     ctx.fillText(s, p-w-2, p+i*r+r/2+f*0.4); }  // draw grid lines ctx.beginPath(); ctx.strokeStyle = "black"; for (var i = 0; i <= n; i++) {     ctx.moveTo(p+r*i, p);     ctx.lineTo(p+r*i, p+r*n);     ctx.moveTo(p, p+r*i);     ctx.lineTo(p+r*n, p+r*i); } ctx.stroke(); 

Резюме

Оператор == в JavaScript совершенно интранзитивен и ущербен. И хоть его недостатки с лихвой покрываются использованием ===, он не настолько ужасен, как показано в некоторых таблицах…

Апдейт

Это было труднее, но всё же получилось сделать таблицу истинности для оператора < (смотрим на jsfiddle):

Таблица истинности для оператора сравнения по форме напоминает треугольник, если расположить её значения в правильном порядке.

(Кстати, принцип упорядочивания значений в таблице истинности для сравнения, не всегда подходит для составления таблиц равенства.)

P.S. от переводчика

Хочется обратить ваше внимание на обсуждение данной статьи на Reddit. На самом деле у оригинальной организации таблицы есть вполне себе веские основания:

ссылка на оригинал статьи http://habrahabr.ru/post/218061/

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *