Почему результат ('b' + 'a' + + 'a' + 'a'). ToLowerCase () 'banana'?


575

Я практиковал JavaScript, когда один из моих друзей наткнулся на этот код JavaScript:

document.write(('b' + 'a' + + 'a' + 'a').toLowerCase());

Код выше отвечает "banana"! Кто-нибудь может объяснить почему?


22
Этот второй плюс - унарный оператор: +"a"есть NaN.
Херардо Фуртадо,

8
В консоли напиши +'a'сам и посмотри что получится.
Какой-то программист чувак

23
И для тех, кто жаждет большего. Посмотреть полный список развлечений
Giddy Naya

4
Сильно связаны: stackoverflow.com/q/9032856
Kyll

Ответы:


566

+'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');


90
'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'

36
('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 есть много похожих игр, которые вы можете проверить.


24

Это просто из-за оператора + .

Мы можем получить дальнейшие знания от куска.

=> ( ('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';

Вы можете преобразовать строку в число двумя способами:

  1. Число (строка);
  2. + Строка;

Итак, вернемся к исходному запросу; Здесь он пытается преобразовать следующий символ ('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);


9

Эта строка кода оценивает выражение и затем вызывает метод на основе возвращенного значения.

Выражение ('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, что оставляет нас с бананом.


7

Использование + преобразует любое значение в число в JavaScript!

Так...

Главное, что нужно знать в первую очередь и извлечь уроки, - это использовать +перед тем, как любое значение в JavaScript, преобразует это значение в число , но если это значение не может быть преобразовано, движок JavaScript вернет NaN , что означает, что не число (не может быть преобразован в число, приятель!) и остальная часть истории, как показано ниже:

Почему результат ('b' + 'a' + + 'a' + 'a'). ToLowerCase () 'banana'?



0

Смотрите магию здесь. Второй плюс это унарный оператор, который дает «NaN»

console.log(('b' + 'a' + + 'a' + 'a').toLowerCase());
console.log(('b' + 'a' + + 'a' + 'a'));
console.log(('b' + 'a' + 'a' + 'a').toLowerCase());

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.