- PVSM.RU - https://www.pvsm.ru -

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

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

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

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

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

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

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

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

Код

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

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 [3]):

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

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

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

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

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

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

Автор: uoziod

Источник [6]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/javascript/58313

Ссылки в тексте:

[1] здесь: http://dorey.github.io/JavaScript-Equality-Table/

[2] jsfiddle: http://jsfiddle.net/G943v/1/

[3] смотрим на jsfiddle: http://jsfiddle.net/G943v/16/

[4] Reddit: http://www.reddit.com/r/programming/comments/21k92r/dont_make_javascript_equality_look_worse_than_it/

[5] вполне себе веские основания: http://www.reddit.com/r/programming/comments/21k92r/dont_make_javascript_equality_look_worse_than_it/cge0be1

[6] Источник: http://habrahabr.ru/post/218061/