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

Вот проблема: какое значение должно быть установлено для переменной «level» в строке 6, чтобы этот код вернул истину? Найдите минутку и подумайте, прежде чем прокручивать страницу вниз.

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

Чтобы вернуть истину, нам нужно пропустить условные выражения в строках 14, 17 и 20. Но как число может быть не меньше, больше или равно случайному числу? Конечно, это невозможно. Но единственные значения внутри «уровней» - это числа.

Как насчет undefined? Когда число сравнивается с неопределенным, оно всегда возвращает false. Итак, все, что нам нужно сделать, это установить для «level» значение, отличное от «easy», «medium» или «hard», что приведет к undefined. Но подождите, мы определяем «уровень» в строке 6, а в строке 8 есть проверка, чтобы убедиться, что уровни [level] правдивы. В противном случае устанавливается значение «средний». Штопать! Мы вернулись к тому, с чего начали.

Пока мы знаем, что уровни [level] не могут быть числом, но они также должны быть правдивыми при оценке в строке 8. Есть ли какие-то скрытые свойства на «уровнях», которых мы не видим? Представляем… прототип! Прототипы - это совершенно другая тема, но вкратце, каждый объект в Javascript имеет прототип, который является объектом, от которого первый объект наследует свойства и методы. Если интерпретатор Javascript не может найти свойство или метод для первого объекта, он проверит прототип этого объекта.

Поскольку «уровни» - это литерал объекта, его прототипом является Object.prototype. На Object.prototype смотреть не особенно интересно, но он содержит некоторые функции, такие как hasOwnProperty () и toString (). Вот почему любой используемый вами объект имеет свойство toString (), даже если оно не было определено для этого объекта.

Обладая этими новообретенными знаниями, мы можем установить «level» для имени функции, такого как «toString». Это пропустит условие в строке 8, поскольку «levels» наследует свойство «toString» от Object.prototype. Это оставляет нам возможность сравнивать случайное число с функцией. Введите в консоль сравнение, например «1‹ toString », и вы действительно получите false. Но что делает Javascript для этого сравнения?

Просматривая исходный код, я не смог найти однозначного ответа о том, что происходит, когда функция используется в сравнении, таком как ‹или›. Однако я знаю, что когда вы используете == с «нечисловыми», он пытается преобразовать это значение в число. Например, «12» превращается в 12, а истина становится равной 1. Попытка преобразовать функцию в число приводит к NaN, а NaN не равно любому другому значению. Следовательно, случайное число - это не ‹,› или == NaN, и мы дойдем до конца и вернем истину!