Является ли оператор JavaScript === доказуемо транзитивным?
JavaScript причудливый слабоспециализированный оператор ==
может быть легко показан как нетранзитивен следующим образом:
var a = "16";
var b = 16;
var c = "0x10";
alert(a == b && b == c && a != c); // alerts true
Интересно, есть ли какие-либо подобные трюки, которые можно играть с ошибкой округления, Infinity
или NaN
, которые могли бы показать, что ===
не является транзитивным, или если он может быть доказан, действительно, является транзитивным.
Ответы
Ответ 1
Оператор ===
в Javascript выглядит как транзитивный, как он может получить.
NaN
надежно отличается от NaN
:
>>> 0/0 === 0/0
false
>>> 0/0 !== 0/0
true
Infinity
достоверно равен Infinity
:
>>> 1/0 === 1/0
true
>>> 1/0 !== 1/0
false
Объекты (хэши) всегда разные:
>>> var a = {}, b = {};
>>> a === b
false
>>> a !== b
true
И поскольку оператор ===
не выполняет никакого принуждения типа, преобразование значения не может иметь значения, поэтому семантика равенства/неравенства примитивных типов останется согласованной (т.е. не противоречит друг другу), несмотря на ошибки интерпретатора.
Ответ 2
Если вы посмотрите на спецификацию (http://bclary.com/2004/11/07/#a-11.9.6), вы увидите, что никакого принуждения типа не производится. Кроме того, все остальное довольно просто, поэтому, возможно, ошибки в реализации сделают его нетранзитивным.
Ответ 3
Предполагая, что у вас есть переменные a, b и c, вы не можете быть на 100% уверенными, как показано здесь. Если кто-то делает что-то хакерское, как указано выше, в производстве, то у вас, вероятно, есть большие проблемы;)
var a = 1;
var b = 1;
Object.defineProperty(window,"c",{get:function(){return b++;}});
alert(a === b && b === c && a !== c); // alerts true