Я практиковал JavaScript, когда один из моих друзей наткнулся на этот код JavaScript:
document.write(('b' + 'a' + + 'a' + 'a').toLowerCase());
Я практиковал JavaScript, когда один из моих друзей наткнулся на этот код JavaScript:
document.write(('b' + 'a' + + 'a' + 'a').toLowerCase());
+'a'
преобразуется в NaN
("Не число"), потому что он приводит строку к числу, в то время как символ a
не может быть проанализирован как число.
document.write(+'a');
'b' + 'a' + + 'a' + 'a'
... оценивается как....
('b') + ('a') + (+'a') + ('a')
(see: operator precedence)
+'a'
пытается преобразовать 'a'
в число с помощью оператора унарный плюс. Поскольку 'a'
не является числом, результат будет NaN
("Не-номер"):
'b' + 'a' + NaN + 'a'
Хотя NaN
обозначает "не число", оно все равно числовой тип; при добавлении в строки он объединяется так же, как и любое другое число:
'b' + 'a' + NaN + 'a' => 'baNaNa'
Наконец, в нижнем регистре:
'baNaNa'.toLowerCase() => 'banana'
('b' + 'a' + + 'a' + 'a').toLowerCase()
Для ясности, давайте разбить это на два этапа. Сначала мы получаем значение выражения в скобках, а затем применяем функцию toLowerCase()
к результату.
'b' + 'a' + + 'a' + 'a'
Идя L-R, мы имеем:
'b' + 'a'
возвращает ba, это обычная конкатенация.ba + + 'a'
пытается объединить ba с + 'a'
. Однако, поскольку унарный оператор +
пытается преобразовать свой операнд в число, возвращается значение NaN, которое затем преобразуется в строку при конкатенации с исходным ba - в результате чего банан.baNaN
+ 'a' возвращает baNaNa. Опять же, это регулярное объединение.
На этом этапе результат первого этапа - baNaNa.
Применение .toLowerCase()
к значению, возвращенному на первом этапе, дает:
banana
В JavaScript есть много похожих каламбуров, которые вы можете проверить.
Это просто из-за + оператора.
Мы можем получить дополнительные знания из этого.
=> ( ('b') + ('a') + (++) + ('a') + ('a'))
=> ( ('b') + ('a') + (+) + ('a') + ('a')) // Here + + convert it to +operator
Which later on try to convert next character to the number.
Например,
const string = '10';
Вы можете преобразовать строку в число двумя способами:
Итак, вернемся к исходному запросу; Здесь он пытается преобразовать следующий символ ('a') в число, но внезапно мы получили ошибку NaN,
( ('b') + ('a') + (+'a') + ('a'))
( ('b') + ('a') + NaN + ('a'))
Но он обрабатывается как строка, потому что предыдущий символ был в строке. Так будет
( ('b') + ('a') + 'NaN' + ('a'))
И, наконец, он преобразует его в toLowerCase(), так что это будет банан
Если вы поставите номер рядом с ним, ваш результат изменится.
( 'b' + 'a' + + '1' + 'a' )
Это будет "ba1a"
const example1 = ('b' + 'a' + + 'a' + 'a').toLowerCase(); // 'banana'
const example2 = ('b' + 'a' + + '1' + 'a').toLowerCase(); // 'ba1a'
console.log(example1);
console.log(example2);
Эта строка кода оценивает выражение, а затем вызывает метод на основе возвращенного значения.
Выражение ('b' + 'a' + + 'a' + 'a')
состоит исключительно из строковых литералов и операторов сложения.
- Строковые литералы "Строковый литерал - это ноль или более символов, заключенных в одинарные или двойные кавычки."
- Оператор сложения (+) "Оператор сложения выполняет либо конкатенацию строк, либо добавление чисел."
Неявное действие - это вызов ToNumber для строки
- ToNumber, примененный к типу строки "ToNumber, примененный к строке, применяет грамматику к входной строке. Если грамматика не может интерпретировать строку как расширение StringNumericLiteral, то результатом ToNumber будет NaN."
У интерпретатора есть правила синтаксического анализа выражения, разбивая его на составляющие левого и правого выражений.
Шаг 1: 'b' + 'a'
Выражение слева: 'b'
Левое значение: 'b'
Оператор: + (одна из сторон выражения является строкой, поэтому конкатенация строк)
Правильное выражение: 'a'
Правильное значение: "а"
Результат: 'ba'
Шаг 2: 'ba' + + 'a'
Выражение слева: 'ba'
Левое значение: 'ba'
Оператор: + (одна из сторон выражения является строкой, поэтому конкатенация строк)
Выражение справа: + 'a'
(это оценивает математическое значение символа 'a', предполагая, что это положительное число от знака + - знак минус также работал бы здесь, указывая отрицательное число - что приводит к NaN)
Правильное значение: NaN (поскольку оператор является конкатенацией строк, toString вызывается для этого значения во время конкатенации)
Результат: "банан"
Шаг 3: 'baNaN' + 'a'
Выражение слева: 'baNaN'
Левое значение: "baNaN"
Оператор: + (одна из сторон выражения является строкой, поэтому конкатенация строк)
Правильное выражение: 'a'
Правильное значение: "а"
Результат: 'baNaNa'
После этого выражение группировки было оценено, и вызывается toLowerCase, что оставляет нас с бананом.
Так...
Главное, что нужно знать первым и извлечь уроки, это использовать +
перед любым значением в JavaScript, преобразует это значение в число, но если это значение не может быть преобразовано, движок JavaScript вернет NaN, что означает , а не число (не может быть преобразовано в число, приятель!), А остальная часть истории, как показано ниже:
Узнайте больше о NaN в W3Schools или сети разработчиков Mozilla
Смотрите магию здесь. Второй плюс - унарный оператор, который дает 'NaN'
console.log(('b' + 'a' + + 'a' + 'a').toLowerCase());
console.log(('b' + 'a' + + 'a' + 'a'));
console.log(('b' + 'a' + 'a' + 'a').toLowerCase());