Я использую JSLint для просмотра JavaScript, и он возвращает много предложений по замене ==
(два знака равенства) с ===
(три знака равенства) при выполнении таких действий, как сравнение idSele_UNVEHtype.value.length == 0
внутри оператора if
.
Есть ли преимущество в производительности при замене ==
на ===
?
Приветствуется любое улучшение производительности, поскольку существует множество операторов сравнения.
Если преобразование типов не происходит, будет ли прирост производительности по сравнению с ==
?
30 ответов
Оператор строгого равенства (===
) ведет себя идентично оператору абстрактного равенства (==
), за исключением того, что преобразование типов не выполняется, и типы должны быть одинаковыми, чтобы считаться равными.
Ссылка: Руководство по Javascript: операторы сравнения
Оператор ==
будет сравнивать на равенство после выполнения всех необходимых преобразований типов . Оператор ===
не выполняет преобразование, поэтому, если два значения не одного типа, ===
просто вернет false
. Оба одинаково быстры.
Процитируя превосходный JavaScript: хорошие моменты Дугласа Крокфорда,
В JavaScript есть два набора операторов равенства:
===
и!==
и их злые близнецы==
и!=
. Хорошие работают так, как вы ожидаете. Если два операнда относятся к одному типу и имеют одинаковое значение, то===
производитtrue
, а!==
производитfalse
. Злые близнецы поступают правильно, когда операнды одного типа, но если они разных типов, они пытаются принудить значения. правила, по которым они это делают, сложны и незабываемы. Вот некоторые из интересных случаев:'' == '0' // false 0 == '' // true 0 == '0' // true false == 'false' // false false == '0' // true false == undefined // false false == null // false null == undefined // true ' \t\r\n ' == 0 // true
Настораживает отсутствие транзитивности. Мой совет - никогда не использовать злых близнецов. Вместо этого всегда используйте
===
и!==
. Все только что показанные сравнения даютfalse
с оператором===
.
Обновить:
Хороший момент был поднят @Casebash в комментариях и в ответ @ Phillipe Laybaert об объектах. Для объектов ==
и ===
действуют согласованно друг с другом (за исключением особого случая).
var a = [1,2,3];
var b = [1,2,3];
var c = { x: 1, y: 2 };
var d = { x: 1, y: 2 };
var e = "text";
var f = "te" + "xt";
a == b // false
a === b // false
c == d // false
c === d // false
e == f // true
e === f // true
Особый случай - это когда вы сравниваете примитив с объектом, который оценивается как тот же примитив, из-за его метода toString
или valueOf
. Например, рассмотрим сравнение строкового примитива со строковым объектом, созданным с помощью конструктора String
.
"abc" == new String("abc") // true
"abc" === new String("abc") // false
Здесь оператор ==
проверяет значения двух объектов и возвращает true
, но ===
видит, что они не одного типа, и возвращает false
. Который правильный? Это действительно зависит от того, что вы пытаетесь сравнить. Мой совет - полностью обойти этот вопрос и просто не использовать конструктор String
для создания строковых объектов из строковых литералов.
Ссылка
http://www.ecma-international.org/ecma- 262 / 5,1 / # сек-11.9.3
В PHP и JavaScript это оператор строгого равенства. Это означает, что он будет сравнивать как тип, так и значения.
В ответах здесь я ничего не читал о том, что означает равно . Некоторые скажут, что ===
означает одинаковые и одного типа , но это не совсем так. Фактически это означает, что оба операнда ссылаются на один и тот же объект или, в случае типов значений, имеют одно и то же значение .
Итак, возьмем следующий код:
var a = [1,2,3];
var b = [1,2,3];
var c = a;
var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true
Тут то же самое:
var a = { x: 1, y: 2 };
var b = { x: 1, y: 2 };
var c = a;
var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true
Или даже:
var a = { };
var b = { };
var c = a;
var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true
Такое поведение не всегда очевидно. В этой истории есть нечто большее, чем равенство и принадлежность к одному типу.
Правило такое:
Для типов значений (чисел):
a === b
возвращает истину, если a
и b
имеют одинаковое значение и одного типа.
Для справочных типов:
a === b
возвращает истину, если a
и b
ссылаются на один и тот же объект.
Для строк:
a === b
возвращает истину, если a
и b
являются строками и содержат одни и те же символы.
Струны: особый случай ...
Строки не являются типами значений, но в Javascript они ведут себя как типы значений, поэтому они будут «равными», когда символы в строке одинаковы и имеют одинаковую длину (как объясняется в третьем правиле)
Теперь становится интересно:
var a = "12" + "3";
var b = "123";
alert(a === b); // returns true, because strings behave like value types
Но как насчет этого ?:
var a = new String("123");
var b = "123";
alert(a === b); // returns false !! (but they are equal and of the same type)
Я думал, что строки ведут себя как типы значений? Ну, это зависит от того, кого вы спросите ... В этом случае a и b не одного типа. a
имеет тип Object
, а b
имеет тип string
. Просто помните, что создание строкового объекта с помощью конструктора String
создает что-то типа Object
, которое ведет себя как строка большую часть времени .
Позвольте мне добавить этот совет:
Если сомневаетесь, прочтите спецификацию !
ECMA-262 - это спецификация языка сценариев, диалектом которого является JavaScript. Конечно, на практике поведение наиболее важных браузеров имеет большее значение, чем эзотерическое определение того, как что-то должно обрабатываться. Но полезно понять, почему new String ("a")! == "a" .
Пожалуйста, позвольте мне объяснить, как читать спецификацию, чтобы прояснить этот вопрос. Я вижу, что в этой очень старой теме никто не дал ответа на очень странный эффект. Итак, если вы можете прочитать спецификацию, это очень поможет вам в вашей профессии. Это приобретенный навык. Итак, продолжим.
Поиск в файле PDF по запросу === приводит меня к странице 56 спецификации: 11.9.4. Оператор строгого равенства (===) , и, пройдя через спецификацию, я нахожу:
11.9.6 Алгоритм сравнения строгого равенства
Сравнение x === y, где x и y - значения, дает истина или ложь . Такое сравнение выполняется следующим образом:
1. Если Тип (x) отличается от Типа (y), вернуть false .
2. Если Type (x) - Undefined, вернуть true .
3. Если Type (x) равен Null, вернуть true .
4. Если Тип (x) не является числом, переходите к шагу 11.
5. Если x равно NaN , вернуть false .
6. Если y равно NaN , вернуть false .
7. Если x имеет то же числовое значение, что и y, вернуть истина .
8. Если x равно +0, а y равно −0, вернуть истина .
9. Если x равно −0, а y равно +0, вернуть истину .
10. Верните false .
11. Если Тип (x) равен String, то вернуть true , если x и y - это одна и та же последовательность символов (одинаковая длина и одинаковые символы в соответствующих позициях); в противном случае верните false .
12. Если Type (x) - Boolean, вернуть true , если x и y оба true или оба false ; в противном случае верните false .
13. Верните true , если x и y относятся к одному и тому же объекту или если они относятся к объектам, соединенным друг с другом (см. 13.1.2). В противном случае верните false .
Интересен шаг 11. Да, строки рассматриваются как типы значений. Но это не объясняет, почему new String ("a")! == "a" . У нас есть браузер, не соответствующий ECMA-262?
Не так быстро!
Проверим типы операндов. Попробуйте сами, заключив их в typeof () . Я обнаружил, что new String ("a") является объектом, и используется шаг 1: вернуть false , если типы различаются.
Если вам интересно, почему new String ("a") не возвращает строку, как насчет упражнения по чтению спецификации? Повеселись!
Айдиакапи написал об этом в комментарии ниже:
Из спецификации
11.2.2 Новый оператор :
Если Type (конструктор) не является Object, генерировать исключение TypeError.
Другими словами, если String не относится к типу Object, его нельзя использовать с оператором new.
new всегда возвращает объект, даже для конструкторов String . Увы! Семантика значений для строк (см. Шаг 11) теряется.
И, наконец, это означает: new String ("a")! == "a" .
Я тестировал это в Firefox с помощью Firebug, используя такой код:
console.time("testEquality");
var n = 0;
while (true) {
n++;
if (n == 100000)
break;
}
console.timeEnd("testEquality");
А также
console.time("testTypeEquality");
var n = 0;
while (true) {
n++;
if (n === 100000)
break;
}
console.timeEnd("testTypeEquality");
Мои результаты (проверены по пять раз и усреднены):
==: 115.2
===: 114.4
Поэтому я бы сказал, что мизерная разница (это более 100000 итераций, помните) незначительна. Эффективность не причина делать ===
. Типовая безопасность (ну, насколько безопасно, как вы собираетесь получить в JavaScript), и качество кода.
==
? Помните, что тогда производительность повышается.
В JavaScript это означает одно и то же значение и тип.
Например,
4 == "4" // will return true
Но
4 === "4" // will return false
Да! Это имеет значение.
Оператор ===
в javascript проверяет значение, а также тип , а оператор ==
просто проверяет значение (при необходимости выполняет преобразование типа) .
Вы можете легко это проверить. Вставьте следующий код в HTML-файл и откройте его в браузере.
<script>
function onPageLoad()
{
var x = "5";
var y = 5;
alert(x === 5);
};
</script>
</head>
<body onload='onPageLoad();'>
В предупреждении вы получите сообщение « false ». Теперь измените метод onPageLoad()
на alert(x == 5);
, вы получите true .
Оператор === называется оператором строгого сравнения, он чем отличается от оператора == .
Возьмем 2 варианта a и b.
Чтобы "a == b" было истинным, a и b должны быть одинаковыми значениями .
В случае "a === b" a и b должны быть одного и того же значения , а также того же типа , чтобы оно оценивалось как правда.
Возьмите следующий пример
var a = 1;
var b = "1";
if (a == b) //evaluates to true as a and b are both 1
{
alert("a == b");
}
if (a === b) //evaluates to false as a is not the same type as b
{
alert("a === b");
}
Вкратце ; использование оператора == может иметь значение true в ситуациях, когда вы этого не хотите, поэтому использование оператора === будет более безопасным.
В сценарии использования 90% не имеет значения, какой из них вы используете, но полезно знать разницу, когда однажды вы обнаружите какое-то неожиданное поведение.
JavaScript ===
vs ==
.
0==false // true
0===false // false, because they are of a different type
1=="1" // true, auto type coercion
1==="1" // false, because they are of a different type
===
проверяет, что одинаковые стороны равны по типу и значению .
Примере:
'1' === 1 // will return "false" because `string` is not a `number`
Типичный пример:
0 == '' // will be "true", but it's very common to want this check to be "false"
Другой распространенный пример:
null == undefined // returns "true", but in most cases a distinction is necessary
Часто бывает удобна нетипизированная проверка, потому что вам все равно, будет ли значение либо undefined
, null
, 0
или ""
Блок-схема выполнения Javascript для строгого равенства / сравнения '==='
Блок-схема выполнения Javascript для нестрогого равенства / сравнения '=='
Почему ==
такой непредсказуемый?
Что вы получите, если сравните пустую строку ""
с нулем 0
?
true
Да, это верно, согласно ==
, что пустая строка и ноль совпадают.
И это еще не все, вот еще один:
'0' == false // true
С массивами все становится действительно странно.
[1] == true // true
[] == false // true
[[]] == false // true
[0] == false // true
Тогда еще страннее со строками
[1,2,3] == '1,2,3' // true - REALLY?!
'\r\n\t' == 0 // true - Come on!
Становится хуже:
Когда равно не равно?
let A = '' // empty string
let B = 0 // zero
let C = '0' // zero string
A == B // true - ok...
B == C // true - so far so good...
A == C // **FALSE** - Plot twist!
Позвольте мне сказать это еще раз:
(A == B) && (B == C) // true
(A == C) // **FALSE**
И это просто безумие, которое можно получить с примитивами.
Когда вы используете ==
с объектами, это совершенно новый уровень безумия.
В этот момент вам, вероятно, интересно ...
Почему это происходит?
Это потому, что в отличие от "тройного равенства" (===
), который просто проверяет, совпадают ли два значения.
==
выполняет целый ряд других функций .
Он имеет специальную обработку для функций, специальную обработку для значений NULL, undefined, строк и т. Д.
Это довольно странно.
Фактически, если вы попытаетесь написать функцию, которая делает то, что делает ==
, она будет выглядеть примерно так:
function isEqual(x, y) { // if `==` were a function
if(typeof y === typeof x) return y === x;
// treat null and undefined the same
var xIsNothing = (y === undefined) || (y === null);
var yIsNothing = (x === undefined) || (x === null);
if(xIsNothing || yIsNothing) return (xIsNothing && yIsNothing);
if(typeof y === "function" || typeof x === "function") {
// if either value is a string
// convert the function into a string and compare
if(typeof x === "string") {
return x === y.toString();
} else if(typeof y === "string") {
return x.toString() === y;
}
return false;
}
if(typeof x === "object") x = toPrimitive(x);
if(typeof y === "object") y = toPrimitive(y);
if(typeof y === typeof x) return y === x;
// convert x and y into numbers if they are not already use the "+" trick
if(typeof x !== "number") x = +x;
if(typeof y !== "number") y = +y;
// actually the real `==` is even more complicated than this, especially in ES6
return x === y;
}
function toPrimitive(obj) {
var value = obj.valueOf();
if(obj !== value) return value;
return obj.toString();
}
Что это значит?
Это означает, что ==
сложно.
Поскольку это сложно, трудно понять, что произойдет, когда вы его используете.
Это означает, что вы можете столкнуться с ошибками.
Итак, мораль этой истории ...
Сделайте свою жизнь менее сложной.
Используйте ===
вместо ==
.
Конец.
В типичном скрипте разницы в производительности не будет. Более важным может быть тот факт, что тысяча "===" на 1 КБ тяжелее тысячи "==" :) профилировщиков JavaScript < / a> может сказать вам, есть ли разница в производительности в вашем случае.
Но лично я бы сделал то, что предлагает JSLint. Эта рекомендация существует не из-за проблем с производительностью, а потому, что приведение типов означает, что ('\t\r\n' == 0)
истинно.
Оператор сравнения равенства == сбивает с толку, и его следует избегать.
Если вы ДОЛЖНЫ смириться с этим, помните следующие 3 вещи:
- Это не транзитивно: (a == b) и (b == c) не приводит к (a == c)
- Он является взаимоисключающим по отношению к своему отрицанию: (a == b) и (a! = B) всегда имеют противоположные логические значения со всеми a и b.
- В случае сомнений выучите наизусть следующую таблицу истинности:
ТАБЛИЦА ИСТИНЫ РАВНОГО ОПЕРАТОРА В JAVASCRIPT
- Каждая строка в таблице представляет собой набор из 3 взаимно «равных» значений, что означает, что любые 2 значения среди них равны с использованием знака равенства == *
** СТРАННО: обратите внимание, что любые два значения в первом столбце не равны в этом смысле. **
'' == 0 == false // Any two values among these 3 ones are equal with the == operator
'0' == 0 == false // Also a set of 3 equal values, note that only 0 and false are repeated
'\t' == 0 == false // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
'\r' == 0 == false // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
'\n' == 0 == false // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
'\t\r\n' == 0 == false // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
null == undefined // These two "default" values are not-equal to any of the listed values above
NaN // NaN is not equal to any thing, even to itself.
Маловероятно, что будет какая-либо разница в производительности между двумя операциями при вашем использовании. Преобразования типа не требуется, поскольку оба параметра уже относятся к одному типу. Обе операции будут иметь сравнение типов, за которым следует сравнение значений.
JSLint иногда дает вам нереальные причины для внесения изменений. ===
имеет ту же производительность, что и ==
, если типы уже совпадают.
Это быстрее, только когда типы не совпадают, и в этом случае он не пытается преобразовать типы, а напрямую возвращает false.
Итак, IMHO, JSLint можно использовать для написания нового кода, но следует избегать бесполезной чрезмерной оптимизации любой ценой.
Это означает, что нет причин менять ==
на ===
в проверке, такой как if (a == 'test')
, если вы точно знаете, что a может быть только String.
Такое изменение большого количества кода тратит время разработчиков и рецензентов и ни к чему не приводит.
a.length===4
на самом деле медленнее в Firefox, чем a.length==4
. В любом случае это микрооптимизация, но это противоречит тому, что люди утверждают.
Оператор ===
проверяет значения, а также типы переменных на равенство.
Оператор ==
просто проверяет значение переменных на равенство.
Простой пример:
2 == '2' -> true, values are SAME because of type conversion.
2 === '2' -> false, values are NOT SAME because of no type conversion.
В двух верхних ответах оба упомянутых == означает равенство, а === означает идентичность. К сожалению, это утверждение неверно.
Если оба операнда == являются объектами, они сравниваются, чтобы увидеть, являются ли они одним и тем же объектом. Если оба операнда указывают на один и тот же объект, оператор равенства возвращает true. В противном случае эти двое не равны.
var a = [1, 2, 3];
var b = [1, 2, 3];
console.log(a == b) // false
console.log(a === b) // false
В приведенном выше коде и ==, и === получают значение false, потому что a и b не являются одними и теми же объектами.
То есть: если оба операнда == являются объектами, == ведет себя так же, как ===, что также означает идентичность. Существенная разница этих двух операторов заключается в преобразовании типов. == имеет преобразование до проверки равенства, а === нет.
Это строгий контрольный тест.
Это хорошо, особенно если вы проверяете от 0 до false и null.
Например, если у вас есть:
$a = 0;
Затем:
$a==0;
$a==NULL;
$a==false;
Все вернет истину, и вы можете этого не захотеть. Предположим, у вас есть функция, которая может возвращать 0-й индекс массива или false в случае ошибки. Если вы проверите с "==" false, вы можете получить запутанный результат.
Итак, с тем же, что и выше, но со строгим тестом:
$a = 0;
$a===0; // returns true
$a===NULL; // returns false
$a===false; // returns false
0 != null
. -1
Просто
==
означает сравнение операндов с приведением типа.
А также
===
означает сравнение операндов без приведения типа.
Приведение типов в JavaScript означает автоматическое преобразование типов данных в другие типы данных.
Например:
123 == "123" // Returns true, because JS coerces string "123" to number 123
// and then goes on to compare `123 == 123`.
123 === "123" // Returns false, because JS does not coerce values of different types here.
Как правило, я бы использовал ===
вместо ==
(и !==
вместо !=
).
Причины объяснены в ответах выше, а также Дуглас Крокфорд довольно ясно об этом говорит (JavaScript: The Хорошие запчасти).
Однако есть одно единственное исключение : == null
- это эффективный способ проверки на "пусто или не определено":
if( value == null ){
// value is either null or undefined
}
Например, jQuery 1.9.1 использует этот шаблон 43 раза, а средство проверки синтаксиса JSHint даже предоставляет eqnull
расслабляющий вариант по этой причине.
Из руководства по стилю jQuery:
Строгие проверки равенства (===) следует использовать в пользу ==. Единственное исключение - проверка на undefined и null посредством null.
// Check for both undefined and null values, for some important reason.
undefOrNull == null;
ИЗМЕНИТЬ 2021-03:
В настоящее время большинство браузеров поддержите нулевой оператор объединения (??
) < / а> и присвоение логического нуля (??=)
, что позволяет более кратко присвоить значение по умолчанию, если переменная пуста или не определена, например:
if (a.speed == null) {
// Set default if null or undefined
a.speed = 42;
}
Можно записать как любую из этих форм
a.speed ??= 42;
a.speed ?? a.speed = 42;
a.speed = a.speed ?? 42;
Проблема в том, что у вас могут легко возникнуть проблемы, поскольку в JavaScript много неявных преобразований, что означает ...
var x = 0;
var isTrue = x == null;
var isFalse = x === null;
Что довольно скоро становится проблемой. Лучший пример того, почему неявное преобразование является «злом», можно найти в этом коде в MFC / C ++. который на самом деле будет компилироваться из-за неявного преобразования из CString в HANDLE, который является типом typedef указателя ...
CString x;
delete x;
Что, очевидно, во время выполнения делает очень неопределенные вещи ...
Google для неявных преобразований в C ++ и STL, чтобы получить некоторые аргументы против этого ...
0 == null
ложно.
Из основной справки по javascript
===
Возвращаетtrue
, если операнды строго равны (см. Выше) без преобразования типа.
Сравнение равенства:
Оператор ==
Возвращает истину, если оба операнда равны. Перед сравнением операнды преобразуются в один и тот же тип.
>>> 1 == 1
true
>>> 1 == 2
false
>>> 1 == '1'
true
Равенство и сравнение типов:
Оператор ===
Возвращает истину, если оба операнда равны и одного типа. Как правило, лучше и безопаснее сравнивать таким образом, потому что здесь нет скрытых преобразований типов.
>>> 1 === '1'
false
>>> 1 === 1
true
Вот удобная сравнительная таблица, в которой показаны произошедшие конверсии и различия между ==
и ===
.
Как говорится в заключении:
«Используйте три равных, если вы полностью не понимаете, какие преобразования происходят для двух равных».
http://dorey.github.io/JavaScript-Equality-Table/
Null и undefined - это ничто, то есть
var a;
var b = null;
Здесь a
и b
не имеют значений. Тогда как 0, false и '' - все значения. Их объединяет то, что все они являются ложными значениями, что означает, что все они удовлетворяют ложным условиям.
Итак, 0, false и '' вместе образуют подгруппу. С другой стороны, значения null и undefined образуют вторую подгруппу. Проверьте сравнения на изображении ниже. null и undefined будут равны. Остальные трое будут равны друг другу. Но все они рассматриваются в JavaScript как ложные.
Это то же самое, что и любой объект (например, {}, массивы и т. Д.), Непустая строка и логическое значение true являются истинными условиями. Но не все они равны.
Использование оператора ==
( Равенство )
true == 1; //true, because 'true' is converted to 1 and then compared
"2" == 2; //true, because "2" is converted to 2 and then compared
Использование оператора ===
( Идентификация )
true === 1; //false
"2" === 2; //false
Это связано с тем, что оператор равенства ==
выполняет приведение типов , что означает, что интерпретатор неявно пытается преобразовать значения перед сравнением.
С другой стороны, оператор идентификации ===
не выполняет приведение типов и, следовательно, не преобразует значения при сравнении.
===
проверяет равенство и тип (называемый strict). Идентичность обычно относится к «одинаковости», которая обеспечивается функцией Object.is
(согласно ES2015).
Вот интересная визуализация сравнения равенства между ==
и ===
.
Источник: https://github.com/dorey/JavaScript-Equality-Table ( демонстрация, унифицированная демонстрация)
var1 === var2
При использовании ===
для проверки равенства JavaScript все как есть.
До оценки ничего не конвертируется.
var1 == var2
При использовании ==
для проверки равенства JavaScript происходят некоторые забавные преобразования .
Резюме равенства в Javascript
Вывод:
Всегда используйте ===
, если вы полностью не понимаете причудливые конверсии, которые происходят с помощью ==
.
==
не является транзитивным! (даже при игнорировании NaN
)
==
нетранзитивен?
a = []
, b = false
и c = [0]
.
Это означает равенство без приведения типов приведение типов означает, что JavaScript не преобразует автоматически любые другие типы данных в строковые типы данных
0==false // true,although they are different types
0===false // false,as they are different types
2=='2' //true,different types,one is string and another is integer but
javaScript convert 2 to string by using == operator
2==='2' //false because by using === operator ,javaScript do not convert
integer to string
2===2 //true because both have same value and same types
Похожие вопросы
Новые вопросы
javascript
По вопросам программирования на ECMAScript (JavaScript/JS) и его различных диалектах/реализациях (кроме ActionScript). Обратите внимание, что JavaScript — это НЕ Java. Включите все теги, относящиеся к вашему вопросу: например, [node.js], [jQuery], [JSON], [ReactJS], [angular], [ember.js], [vue.js], [typescript], [стройный] и т. д.
(-0).toString()
как"0"
, но не во всех языках (например, в C#Math.Round(-0.1).ToString()
равно"-0"
). Это может привести к странным исправлениям, таким какx == 0 ? 0 : x
.(-0).toString()
вы уверены, что(-0)
даже создает отрицательный ноль? (Вероятно, это связано с тем, являются ли символы знака частью синтаксической грамматики для литералов Javascript или, как и во многих других языках,-0
является унарным отрицанием, применяемым к литералу, состоящему только из цифр)(-0)
представляет собой применение унарного минуса к литералу, состоящему только из цифр: tc39.es/ecma262/#sec-literals-numeric-literals Но, несмотря на это, формирует отрицательный нуль.