【例句】 Возможно ли, что (a ==1 && a== 2 && a==3) верно?

JavaScript опрос
【例句】 Возможно ли, что (a ==1 && a== 2 && a==3) верно?
Оригинальная ссылка:stackoverflow.com/questions/4…
Дополнительные статьи см.: GitHub.com/elevenbeans…

Интересный вопрос:

В JavaScript,(a ==1 && a== 2 && a==3)Возможно лиtrue?

Это вопрос интервью, который мне задали в технологической компании. Это случилось две недели назад, и я до сих пор не могу найти ответ.

Я знаю, что мы никогда не пишем такой код в нашей повседневной работе, но мне все еще очень интересно узнать ответ на этот вопрос.

Решение первое:

Используйте свободный оператор равенства==работает, вы можете просто создать пользовательскийtoString( илиvalueOf), меняя возвращаемое значение при каждом использовании, чтобы оно удовлетворяло всем трем условиям.

123456789101112
const a = {  i: 1,  toString: function () {    return a.i++;  }}if(a == 1 && a == 2 && a == 3) {  console.log('Hello World!');}// Hello World!

Этот результат связан с нечетким оператором равенства, используемым в выражении==. При использовании свободного равенства, если один из операндов имеет другой тип, чем другой, механизм JS попытается преобразовать одну операцию в другую. В случае объекта слева и числа справа он попытается преобразовать объект в число, сначала вызвавvalueOfЕсли это можно назвать. В противном случае он вызоветtoStringметод. я используюtoStringПросто потому, что это была моя первая реакция,valueOfбыло бы разумнее. если я неtoStringВозвращая строку (вместо возврата числа), движок JS попытается преобразовать строку в число, и хотя путь немного длиннее, он все равно даст нам тот же результат.

Решение второе:

Я не могу этого отрицать - другие ответы, несомненно, верны, но вы действительно не можете ошибиться в приведенном ниже коде:

123456
var aᅠ = 1;var a = 2;var ᅠa = 3;if(aᅠ==1 && a== 2 &&ᅠa==3) {    console.log("Why hello there!")}

осторожностьifСтранный пробел в утверждениях. Это полуширинный корейский =,=. Это символ пробела Unicode, но ECMAScript не интерпретирует его как пробел, что означает, что это допустимый идентификатор. Таким образом, есть три совершенно разные переменные, одна из которыхaПосле добавления полуширинного корейскогоa, одинaДобавьте полуширинный кореец спереди. . .

подчеркивать_Вместо полуширинного корейского для повышения читабельности тот же код выглядит так:

123456
var a_ = 1;var a = 2;var _a = 3;if(a_==1 && a== 2 &&_a==3) {    console.log("Why hello there!")}

Решение третье:

Это вполне возможно!

123456789
var val = 0;Object.defineProperty(window, 'a', {  get: function() {    return ++val;  }});if (a == 1 && a == 2 && a == 3) {  console.log('yay');}

использоватьget,ПозволятьaВозвращаемое значение — три разных значения. Однако это не означает, что мы должны использовать его в реальном коде. . .

И так далее…

Суммировать

1. Используйте свободный оператор равенства==принцип, обычайtoStringа такжеvalueOfвернуть соответствующее значение

2. Использование специальных символов, таких как корейский язык половинной ширины, для воспроизведения «метода запутывания», по сути, не помогло решить проблему.

3. Перехват JS-объектовgetter, но так для строгого равенства===одинаково действительный