Я практиковал JavaScript, когда один из моих друзей наткнулся на этот код JavaScript:
document.write(('b' + 'a' + + 'a' + 'a').toLowerCase());
Код выше отвечает "banana"
! Кто-нибудь может объяснить почему?
+'a'
сам и посмотри что получится.
Я практиковал JavaScript, когда один из моих друзей наткнулся на этот код JavaScript:
document.write(('b' + 'a' + + 'a' + 'a').toLowerCase());
Код выше отвечает "banana"
! Кто-нибудь может объяснить почему?
+'a'
сам и посмотри что получится.
Ответы:
+'a'
разрешается в NaN
("Not a Number"), потому что он приводит строку к числу, в то время как символ a
не может быть проанализирован как число.
document.write(+'a');
banana
.
Добавление NaN
к "ba"
превращается NaN
в строку "NaN"
из-за преобразования типа, дает baNaN
. И тогда есть a
зад, давая baNaNa
.
Пространство между + +
должно сделать конкатенацию первой строки, а второй оператор унарным плюсом (то есть «положительным»). У вас будет тот же результат, если вы используете 'ba'+(+'a')+'a'
, разрешенный как 'ba'+NaN+'a'
, что эквивалентно 'ba'+'NaN'+'a'
из-за жонглирования типа.
document.write('ba'+(+'a')+'a');
'b' + 'a' + + 'a' + 'a'
... оценивается как ....
('b') + ('a') + (+'a') + ('a')
(см .: приоритет оператора )
(+'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'
Собираясь в ЛР , имеем:
'b' + 'a'
возвращает ba , это регулярная конкатенация.ba + + 'a'
попытки объединить ба с + 'a'
. Однако, поскольку унарный оператор +
пытается преобразовать свой операнд в число, возвращается значение NaN , которое затем преобразуется в строку при конкатенации с исходным ba, что приводит к baNaN .baNaN
+ 'a' возвращает baNaNa . Опять же, это регулярное объединение.
На данном этапе результатом первого этапа является baNaNa .
Применение .toLowerCase()
к значению, возвращенному на первом этапе, дает:
банан
В 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 Developer Network
Смотрите магию здесь. Второй плюс это унарный оператор, который дает «NaN»
console.log(('b' + 'a' + + 'a' + 'a').toLowerCase());
console.log(('b' + 'a' + + 'a' + 'a'));
console.log(('b' + 'a' + 'a' + 'a').toLowerCase());
+"a"
естьNaN
.