Может ли (a == 1 && a == 2 && a == 3) когда-либо оценивать значение true?

Замечание модератора: Пожалуйста, сопротивляйтесь желанию изменить код или удалить это уведомление. Шаблон пробела может быть частью вопроса, и поэтому его не следует подделывать без необходимости. Если вы находитесь в лагере "пробелы - незначителен", вы должны иметь возможность принимать код как есть.

Возможно ли, что (a== 1 && a ==2 && a==3) может оценить true в JavaScript?

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

+2399
15 янв. '18 в 20:20
источник поделиться
30 ответов

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

const a = {
  i: 1,
  toString: function () {
    return a.i++;
  }
}

if(a == 1 && a == 2 && a == 3) {
  console.log('Hello World!');
}

Причина, по которой это работает, связана с использованием свободного оператора равенства. При использовании свободного равенства, если один из операндов отличается от другого, движок будет пытаться преобразовать один в другой. В случае объекта слева и числа справа он попытается преобразовать объект в число, сначала вызвав valueOf, если он является вызываемым, и в противном случае он вызовет toString. В этом случае я использовал toString просто потому, что это пришло в голову, valueOf имело бы больше смысла. Если бы я вместо этого вернул строку из toString, тогда движок попытался бы преобразовать строку в число, давая нам тот же конечный результат, хотя и с немного более длинным путем.

+3243
15 янв. '18 в 20:35
источник

Связанные вопросы


Похожие вопросы

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

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

Обратите внимание на странное расстояние в инструкции if (которую я скопировал из вашего вопроса). Это полуширина Hangul (что корейский для тех, кто не знаком), который является символом пробела Unicode, который не интерпретируется ECMA script как символ пробела - это означает, что он является допустимым символом для идентификатора. Поэтому есть три совершенно разные переменные: одна с хангулом после a, одна с ней до и последняя с просто a. Заменяя пространство с помощью _ для удобства чтения, тот же код будет выглядеть так:

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

Отметьте подтверждение проверки валидатора переменных Mathias. Если бы этот странный интервал был фактически включен в их вопрос, я уверен, что это намек на такой ответ.

Не делай этого. Серьезно.

Изменить: мне пришло в голову, что (хотя и не разрешено запускать переменную) Zero-width joiner и Имена символов с нулевой шириной допускаются также в именах переменных - см. Обфускация JavaScript с символами нулевой ширины - профи и минусы?.

Это будет выглядеть следующим образом:

var a= 1;
var a‍= 2; //one zero-width character
var a‍‍= 3; //two zero-width characters (or you can use the other one)
if(a==1&&a‍==2&&a‍‍==3) {
    console.log("Why hello there!")
}
+2015
16 янв. '18 в 5:14
источник

ЭТО ВОЗМОЖНО!

var i = 0;

with({
  get a() {
    return ++i;
  }
}) {
  if (a == 1 && a == 2 && a == 3)
    console.log("wohoo");
}

При этом используется поглотитель внутри with выражением, чтобы оценка три различных значений. a

... это все еще не означает, что это должно использоваться в реальном коде...

Хуже того, этот трюк также будет работать с использованием ===.

  var i = 0;

  with({
    get a() {
      return ++i;
    }
  }) {
    if (a !== a)
      console.log("yep, this is printed.");
  }
+604
15 янв. '18 в 20:35
источник

Пример без геттеров или значения:

a = [1,2,3];
a.join = a.shift;
console.log(a == 1 && a == 2 && a == 3);

Это работает, потому что == вызывает toString которая вызывает .join для массивов.

Другое решение, использующее Symbol.toPrimitive которое в ES6 эквивалентно toString/valueOf:

let i = 0;
let a = { [Symbol.toPrimitive]: () => ++i };

console.log(a == 1 && a == 2 && a == 3);
+487
17 янв. '18 в 11:37
источник

Если задано, возможно ли (НЕ ДОЛЖНО), он может попросить "а" вернуть случайное число. Было бы правдой, если бы он последовательно генерировал 1, 2 и 3.

with({
  get a() {
    return Math.floor(Math.random()*4);
  }
}){
  for(var i=0;i<1000;i++){
    if (a == 1 && a == 2 && a == 3){
      console.log("after " + (i+1) + " trials, it becomes true finally!!!");
      break;
    }
  }
}
+264
16 янв. '18 в 6:21
источник

Если вы не можете ничего сделать без регулярных выражений:

var a = {
  r: /\d/g, 
  valueOf: function(){
    return this.r.exec(123)[0]
  }
}

if (a == 1 && a == 2 && a == 3) {
    console.log("!")
}

Он работает из-за пользовательского метода valueOf, который вызывается, когда объект сравнивается с примитивным (например, Number). Главный трюк заключается в том, что a.valueOf возвращает новое значение каждый раз, потому что он вызывает exec в регулярном выражении с флагом g, что вызывает обновление lastIndex этого регулярного выражения каждый раз, когда найдено совпадение. Итак, в первый раз this.r.lastIndex == 0 он соответствует 1 и обновляет lastIndex: this.r.lastIndex == 1, поэтому следующее регулярное выражение будет соответствовать 2 и т.д.

+205
16 янв. '18 в 19:35
источник

Это можно сделать, используя следующее в глобальной области. Для nodejs используйте global вместо window в приведенном ниже коде.

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

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

+188
15 янв. '18 в 20:37
источник

Это возможно в случае обращения к переменной a, скажем, 2 веб-работникам через SharedArrayBuffer, а также некоторые основные script. Возможность низкая, но возможно, что когда код компилируется в машинный код, рабочие сети обновляют переменную a как раз вовремя, поэтому выполняются условия a==1, a==2 и a==3.

Это может быть пример состояния гонки в многопоточной среде, предоставляемой веб-работниками и SharedArrayBuffer в JavaScript.

Вот базовая реализация выше:

main.js

// Main Thread

const worker = new Worker('worker.js')
const modifiers = [new Worker('modifier.js'), new Worker('modifier.js')] // Let use 2 workers
const sab = new SharedArrayBuffer(1)

modifiers.forEach(m => m.postMessage(sab))
worker.postMessage(sab)

worker.js

let array

Object.defineProperty(self, 'a', {
  get() {
    return array[0]
  }
});

addEventListener('message', ({data}) => {
    array = new Uint8Array(data)
    let count = 0
    do {
        var res = a == 1 && a == 2 && a == 3
        ++count
    } while(res == false) // just for clarity. !res is fine
    console.log(`It happened after ${count} iterations`)
    console.log('You should\'ve never seen this')
})

modifier.js

addEventListener('message' , ({data}) => {
    setInterval( () => {
        new Uint8Array(data)[0] = Math.floor(Math.random()*3) + 1
    })
})

На моем MacBook Air это происходит после примерно 10 миллиардов итераций с первой попытки:

введите описание изображения здесь

Вторая попытка:

введите описание изображения здесь

Как я уже сказал, шансы будут низкими, но, учитывая достаточное время, он попадет в состояние.

Совет. Если в вашей системе слишком много времени. Попробуйте только a == 1 && a == 2 и измените Math.random()*3 на Math.random()*2. Добавление все большего количества в список снижает вероятность удара.

+186
17 янв. '18 в 7:39
источник

Это также возможно с помощью серии самонастраиваемых геттеров:

(Это похоже на решение jontro, но не требует переменной счетчика.)

(() => {
    "use strict";
    Object.defineProperty(this, "a", {
        "get": () => {
            Object.defineProperty(this, "a", {
                "get": () => {
                    Object.defineProperty(this, "a", {
                        "get": () => {
                            return 3;
                        }
                    });
                    return 2;
                },
                configurable: true
            });
            return 1;
        },
        configurable: true
    });
    if (a == 1 && a == 2 && a == 3) {
        document.body.append("Yes, it’s possible.");
    }
})();
+145
16 янв. '18 в 11:37
источник

Я не вижу, что этот ответ уже отправлен, поэтому я тоже заброшу его в микс. Это похоже на ответ Джеффа с пространством хангула полуширины.

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

Вы можете заметить небольшое несоответствие со вторым, но первое и третье идентичны невооруженным глазом. Все 3 - разные символы:

a - латинский нижний регистр A
- Полная ширина латинского нижнего регистра A
а - кириллический нижний регистр A

Общий термин для этого - "гомоглифы": разные символы юникода, которые выглядят одинаково. Обычно трудно получить три, которые совершенно неразличимы, но в некоторых случаях вам может повезти. A, A, А и Ꭺ будут работать лучше (Latin-A, Greek Alpha, Кириллица-A и Cherokee-A соответственно, к сожалению, буквы в нижнем регистре греческого и чероки слишком отличаются от Latin a: α, , и поэтому не помогает с приведенным выше фрагментом).

Там есть целый класс Homoglyph Attacks, чаще всего в поддельных доменных именах (например, wikipediа.org (кириллица) vs wikipedia.org (латинский)), но он также может отображаться в коде; обычно упоминаемый как подкупленный (как упоминалось в комментарии, [underhanded] вопросы теперь не соответствуют теме PPCG, но обычно это был тип проблемы, когда такие вещи появлялись). Я использовал этот сайт, чтобы найти гомоглифы, используемые для этого ответа.

+128
16 янв. '18 в 18:44
источник

В качестве альтернативы вы можете использовать для него класс и экземпляр для проверки.

function A() {
    var value = 0;
    this.valueOf = function () { return ++value; };
}

var a = new A;

if (a == 1 && a == 2 && a == 3) {
    console.log('bingo!');
}

ИЗМЕНИТЬ

Используя классы ES6, это будет выглядеть как

class A {
  constructor() {
    this.value = 0;
    this.valueOf();
  }
  valueOf() {
    return this.value++;
  };
}

let a = new A;

if (a == 1 && a == 2 && a == 3) {
  console.log('bingo!');
}
+125
16 янв. '18 в 15:11
источник

Да, это возможно! 😎

"JavaScript

if‌=()=>!0;
var a = 9;

if‌(a==1 && a== 2 && a==3)
{
    document.write("<h1>Yes, it is possible!😎</h1>")
}

Вышеприведенный код является короткой версией (благодаря @Forivin для примечания в комментариях), и следующий код является оригинальным:

var a = 9;

if‌(a==1 && a== 2 && a==3)
{
    //console.log("Yes, it is possible!😎")
    document.write("<h1>Yes, it is possible!😎</h1>")
}

//--------------------------------------------

function if‌(){return true;}

Если вы просто видите верхнюю часть моего кода и запускаете его, вы говорите WOW, как?

Поэтому я думаю, что достаточно сказать "Да", возможно, кто-то сказал вам: "Нет ничего невозможного"

Trick: Я использовал скрытый символ после if как сделать функцию, чтобы ее имя было похоже на if. В JavaScript мы не можем переопределять ключевые слова, поэтому я вынужден использовать этот способ. Это подделка, if, но она работает для вас в этом случае!


" С#

Также я написал версию С# (с повышением стоимости свойства):

static int _a;
public static int a => ++_a;

public static void Main()
{
    if(a==1 && a==2 && a==3)
    {
        Console.WriteLine("Yes, it is possible!😎");
    }
}

Демо-версия

+100
21 янв. '18 в 1:59
источник

JavaScript

a == a +1

В JavaScript нет целых чисел, но только Number s, которые реализованы как числа с плавающей запятой двойной точности.

Это означает, что если число a достаточно велико, его можно считать равным трем целым целым числам:

a = 100000000000000000
if (a == a+1 && a == a+2 && a == a+3){
  console.log("Precision loss!");
}

Правда, это не совсем то, о чем попросил интервьюер (он не работает с a=0), но это не связано с трюком со скрытыми функциями или перегрузкой оператора.

Другие языки

Для справки, в Ruby и Python есть a==1 && a==2 && a==3 решения. С небольшой модификацией это также возможно на Java.

Рубин

С пользовательским ==:

class A
  def ==(o)
    true
  end
end

a = A.new

if a == 1 && a == 2 && a == 3
  puts "Don't do this!"
end

Или увеличение: a

def a
  @a ||= 0
  @a += 1
end

if a == 1 && a == 2 && a == 3
  puts "Don't do this!"
end

питон

class A:
    def __eq__(self, who_cares):
        return True
a = A()

if a == 1 and a == 2 and a == 3:
    print("Don't do that!")

Джава

Возможно изменение кеша Java Integer:

package stackoverflow;

import java.lang.reflect.Field;

public class IntegerMess
{
    public static void main(String[] args) throws Exception {
        Field valueField = Integer.class.getDeclaredField("value");
        valueField.setAccessible(true);
        valueField.setInt(1, valueField.getInt(42));
        valueField.setInt(2, valueField.getInt(42));
        valueField.setInt(3, valueField.getInt(42));
        valueField.setAccessible(false);

        Integer a = 42;

        if (a.equals(1) && a.equals(2) && a.equals(3)) {
            System.out.println("Bad idea.");
        }
    }
}
+95
17 янв. '18 в 10:14
источник

Это инвертированная версия @Jeff answer *, где скрытый символ (U + 115F, U + 1160 или U + 3164) используется для создания переменных, которые выглядят как 1, 2 и 3.

var  a = 1;
var ᅠ1 = a;
var ᅠ2 = a;
var ᅠ3 = a;
console.log( a ==ᅠ1 && a ==ᅠ2 && a ==ᅠ3 );

* Этот ответ может быть упрощен за счет использования нулевой ширины (U + 200C) и стопоров нулевой ширины (U + 200D). Оба этих символа допускаются внутри идентификаторов, но не в начале:

var a = 1;
var a‌ = 2;
var a‍ = 3;
console.log(a == 1 && a‌ == 2 && a‍ == 3);

/****
var a = 1;
var a\u200c = 2;
var a\u200d = 3;
console.log(a == 1 && a\u200c == 2 && a\u200d == 3);
****/

Другие трюки возможны с использованием той же идеи, например. с помощью селекторов вариаций Unicode для создания переменных, которые выглядят совершенно одинаково (a︀ = 1; a︁ = 2; a︀ == 1 && a︁ == 2; // true).

+79
18 янв. '18 в 10:51
источник

Правило номер один из интервью; никогда не сказать невозможным.

Не нужно скрывать трюки персонажа.

window.__defineGetter__( 'a', function(){
    if( typeof i !== 'number' ){
        // define i in the global namespace so that it not lost after this function runs
        i = 0;
    }
    return ++i;
});

if( a == 1 && a == 2 && a == 3 ){
    alert( 'Oh dear, what have we done?' );
}
+73
16 янв. '18 в 17:27
источник

Честно говоря, есть ли способ оценить его истинным или нет (и, как показали другие, существует несколько способов), ответ, который я бы искал, выступая как человек, который провел сотни интервью, было бы чем-то вроде:

"Ну, может быть, да при некоторых странных условиях, которые мне сразу не очевидны... но если бы я столкнулся с этим в реальном коде, я бы использовал общие методы отладки, чтобы выяснить, как и почему он делает то, что он делал, а затем сразу же рефакторировал код, чтобы избежать этой ситуации... но что более важно: я бы НИКОГДА не писал этот код в первую очередь, потому что это само определение свернутого кода, и я стараюсь никогда не писать сложный код".

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

+68
16 янв. '18 в 21:57
источник

Если вы когда-нибудь зададите такой вопрос интервью (или обратите внимание на какое-то столь же неожиданное поведение в вашем коде), подумайте о том, какие вещи могут привести к поведению, которое выглядит на первый взгляд невозможным:

  1. Кодировка: в этом случае переменная, на которую вы смотрите, не та, которую вы считаете. Это может произойти, если вы намеренно возитесь с Unicode с помощью гомоглифов или пробелов, чтобы сделать имя переменной похожим на другое, но проблемы с кодировкой также могут быть введены случайно, например, при копировании и вставке кода из Интернета, который содержит неожиданный код Unicode (например, из-за того, что система управления контентом выполняла некоторые "автоматическое форматирование", такие как замена fl на Unicode "LATIN SMALL LIGATURE FL" (U + FB02)).

  2. Условия гонки: может возникнуть состояние гонки, то есть ситуация, когда код не выполняется в последовательности, ожидаемой разработчиком. Условия гонки часто бывают в многопоточном коде, но несколько потоков не являются обязательным условием для условий гонки. Асинхронность достаточна (и не смущайтесь, асинхронность не означает, что под капотом используются несколько потоков).

    Обратите внимание, что поэтому JavaScript также не свободен от условий гонки только потому, что он однопоточный. См. Здесь простой однопоточный, но асинхронный пример. В контексте одного заявления условие гонки, однако, было бы довольно трудно попасть в JavaScript.

    JavaScript с веб-работниками немного отличается, так как вы можете иметь несколько потоков. @mehulmpt показал нам отличное доказательство концепции с использованием веб-работников.

  3. Побочные эффекты: побочный эффект операции сравнения равенства (который не должен быть столь же очевидным, как в примерах здесь, часто побочные эффекты очень тонкие).

Такого рода вопросы может появляться во многих языках программирования, а не только JavaScript, поэтому мы не видим один из классического JavaScript WTFs здесь 1.

Конечно, вопрос интервью и образцы здесь все выглядят очень надуманными. Но они являются хорошим напоминанием о том, что:

  • Побочные эффекты могут стать действительно неприятными и что хорошо продуманная программа должна быть свободна от нежелательных побочных эффектов.
  • Многопоточное и изменяемое состояние может быть проблематичным.
  • Неправильное кодирование символов и правильная обработка строк могут привести к неприятным ошибкам.

1 Например, вы можете найти пример в совершенно другом языке программирования (С#) экспонирование побочного эффекта (очевидный) здесь.

+41
17 янв. '18 в 12:57
источник

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

const a = {
  n: [3,2,1],
  toString: function () {
    return a.n.pop();
  }
}

if(a == 1 && a == 2 && a == 3) {
  console.log('Yes');
}
+41
16 янв. '18 в 20:00
источник

Хорошо, еще один взлом с генераторами:

const value = function* () {
  let i = 0;
  while(true) yield ++i;
}();

Object.defineProperty(this, 'a', {
  get() {
    return value.next().value;
  }
});

if (a === 1 && a === 2 && a === 3) {
  console.log('yo!');
}
+31
16 янв. '18 в 21:33
источник

Использование прокси:

var a = new Proxy({ i: 0 }, {
    get: (target, name) => name === Symbol.toPrimitive ? () => ++target.i : target[name],
});
console.log(a == 1 && a == 2 && a == 3);

Прокси в основном претендуют на то, чтобы быть целевым объектом (первый параметр), но перехватывают операции на целевом объекте (в данном случае операция "get property"), так что есть возможность сделать что-то отличное от поведения объекта по умолчанию. В этом случае "получить свойство" действие вызываются когда a == принуждает его тип, чтобы сравнить его с каждым номером. Бывает:

  1. Мы создаем целевой объект { i: 0 }, где свойство i является нашим счетчиком
  2. Мы создаем прокси для целевого объекта и присвоить его a
  3. Для каждого a == сравнения, тип приводятся к примитивному значению a
  4. a[Symbol.toPrimitive]() этого типа приводит к внутреннему вызову a[Symbol.toPrimitive]()
  5. Прокси перехватывает получение функции a[Symbol.toPrimitive] используя "обработчик получения"
  6. Прокси-обработчик "get" проверяет, что полученное свойство имеет вид Symbol.toPrimitive, и в этом случае оно увеличивает значение, а затем возвращает счетчик из целевого объекта: ++target.i. Если извлекается другое свойство, мы просто возвращаемся к возвращению значения свойства по умолчанию, target[name]

Так:

var a = ...; // a.valueOf == target.i == 0
a == 1 && // a == ++target.i == 1
a == 2 && // a == ++target.i == 2
a == 3    // a == ++target.i == 3

Как и с большинством других ответов, это работает только с произвольной проверкой равенства (==), потому что строгие проверки на равенство (===) не приводят к принуждению типов, которое может перехватить Прокси.

+27
19 янв. '18 в 22:19
источник

На самом деле ответ на первую часть вопроса "Да" на каждом языке программирования. Например, это относится к C/С++:

#define a   (b++)
int b = 1;
if (a ==1 && a== 2 && a==3) {
    std::cout << "Yes, it possible!" << std::endl;
} else {
    std::cout << "it impossible!" << std::endl;
}
+27
16 янв. '18 в 19:56
источник

То же, но другое, но все же одно (может быть "проверено" несколько раз):

const a = { valueOf: () => this.n = (this.n || 0) % 3 + 1}
    
if(a == 1 && a == 2 && a == 3) {
  console.log('Hello World!');
}

if(a == 1 && a == 2 && a == 3) {
  console.log('Hello World!');
}

Моя идея началась с того, как работает уравнение типа объекта типа.

+26
17 янв. '18 в 14:18
источник

Ответ ECMAScript 6, в котором используются символы:

const a = {value: 1};
a[Symbol.toPrimitive] = function() { return this.value++ };
console.log((a == 1 && a == 2 && a == 3));

Благодаря == использования, JavaScript должен принуждать в нечто близкое к второму операнду (a 1, 2, 3 в данном случае). Но перед тем, как JavaScript попытается Symbol.toPrimitive принуждение самостоятельно, он пытается вызвать Symbol.toPrimitive. Если вы предоставите Symbol.toPrimitive JavaScript, используйте значение, возвращаемое вашей функцией. Если нет, JavaScript будет вызывать valueOf.

+24
17 янв. '18 в 15:21
источник

Я думаю, что это минимальный код для его реализации:

i=0,a={valueOf:()=>++i}

if (a == 1 && a == 2 && a == 3) {
  console.log('Mind === Blown');
}

Создание фиктивного объекта с пользовательским valueOf, который увеличивает глобальную переменную i для каждого вызова. 23 символа!

+23
21 янв. '18 в 16:31
источник

Этот использует свойство defineProperty с хорошим побочным эффектом, вызывающим глобальную переменную!

var _a = 1

Object.defineProperty(this, "a", {
  "get": () => {
    return _a++;
  },
  configurable: true
});

console.log(a)
console.log(a)
console.log(a)
+12
16 янв. '18 в 19:04
источник

Основной причиной, почему это может быть равным, является оператор ==. С === это не сработает.

const a = {
    i: 0;
    valueOf: function() {
       return this.i++;
    }
}

if(a == 1 && a == 2 && a == 3) // true

Поскольку методы valueOf и toString будут вызываться, когда используются операторы ==.

if(a === 1 && a === 2 && a === 3) // false

Методы valueOf и toString не вызываются.

+2
25 янв. '18 в 7:28
источник

попробуй это :
То же самое, но другое, но все же (можно "проверить" несколько раз):

const a = { valueOf: () => this.n = (this.n || 0) % 3 + 1}

if(a == 1 && a == 2 && a == 3) {
  console.log('Hello World!');
}

if(a == 1 && a == 2 && a == 3) {
  console.log('Hello World!');
}
0
06 июн. '19 в 15:31
источник

Это хороший вопрос. Я также хотел добавить реализацию Java, потому что обновление valueOf() в основном переопределяет функцию базового класса. Мне потребовалось несколько минут, чтобы понять, как это работает в JS, поэтому я сопоставил его с Java для понимания.

public class TestClass {

    int value;

    TestClass() {
        this.value = 0;
    }

    @Override
    public String toString() {
        System.out.println("current " + this.value);
        this.value++;
        return String.valueOf(this.value);
    }
}

class CallingClass {

    public static void main(String[] args) {

        TestClass object = new TestClass();
        if (object.toString().equals("1") && object.toString().equals("2") && object.toString().equals("3")) {
            System.out.print("it here");
        }
    }
}
0
24 янв. '19 в 14:40
источник

Переопределив значение valueOf в объявлении класса, это можно сделать:

class Thing {
    constructor() {
        this.value = 1;
    }

    valueOf() {
        return this.value++;
    }
}

const a = new Thing();

if(a == 1 && a == 2 && a == 3) {
    console.log(a);
}

Что происходит, так это то, что valueOf вызывается в каждом операторе сравнения. В первом случае a будет равно 1, во втором a 2, и так далее, и т.д., Потому что каждый раз, когда вызывается valueOf, значение a увеличивается.

Поэтому console.log будет запускать и выводить (в любом случае в моем терминале) Thing: { value: 4}, указывая, что условие было истинным.

0
04 нояб. '18 в 18:55
источник

Даже без путаницы именования, перегрузки или случайных переменных a == 1 && a == 2 && a == 3 может возвращать true в многопоточных средах, так как значение a может меняться между каждым сравнением, если оно не является потокобезопасным.

-3
16 янв. '18 в 19:59
источник

Посмотрите другие вопросы по меткам или Задайте вопрос