Чому результат ('b' + 'a' + + 'a' + 'a'). ToLowerCase () 'банан'?


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("Не число"), оскільки він примушує рядок до числа, тоді як символ 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'на число за допомогою оператора unary plus . Оскільки 'a'це не число, результат є NaN ( "Не-A-Number" ):

'b'  +  'a'  +  NaN  + 'a'

Хоча NaNозначає "Не число", це все ж числовий тип ; при додаванні до рядків він об'єднує так само, як і будь-яке інше число:

'b'  +  'a'  +  NaN  + 'a'  =>  'baNaNa'

Нарешті, це нижній регістр:

'baNaNa'.toLowerCase()      =>  'banana'

36
('b' + 'a' + + 'a' + 'a').toLowerCase()

Для наочності давайте розділимо це на два етапи. Спочатку ми отримуємо значення виразів у дужках, а потім застосовуємо toLowerCase()функцію до результату.

Крок перший

'b' + 'a' + + 'a' + 'a'

Збираючись LR , у нас є:

  • 'b' + 'a'повертає ба , це регулярне конкатенація.
  • 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, застосований до Strings, застосовує граматику до вхідної String. Якщо граматика не може інтерпретувати String як розширення StringNumericLiteral, то результатом ToNumber є NaN."

У перекладача є правила, як розбирати вираз, розбиваючи його на складові виразів лівої та правої руки.


Крок 1: 'b' + 'a'

Лівий вираз: 'b'
ліве значення: 'b'

Оператор: + (одна із сторін виразу - рядок, тому з'єднання рядків)

Правий вираз: 'a' правильне значення: 'a'

Результат: 'ba'


Крок 2: 'ba' + + 'a'

Вираз ліворуч: 'ba'
ліве значення: 'ba'

Оператор: + (одна із сторін виразу - рядок, тому з'єднання рядків)

Правий вираз: + 'a'(це оцінює значення математики символу 'a', припускаючи, що це додатне число від знаку + - знак мінус також працював би тут, вказуючи негативне число - що призводить до NaN)
Правильне значення: NaN (оскільки оператор є об'єднанням рядків, toString викликається цим значенням під час конкатенації)

Результат: 'baNaN'


Крок 3: 'baNaN' + 'a'

Вираз ліворуч: 'baNaN'
ліве значення: 'baNaN'

Оператор: + (одна із сторін виразу - рядок, тому з'єднання рядків)

Правий вираз: 'a'
правильне значення: 'a'

Результат: 'baNaNa'


Після цього оцінюється вираз групування, і називається toLowerCase, який залишає нас з бананом.


7

Використання + перетворить будь-яке значення в Число в JavaScript!

Тому...

Тут головне, що потрібно знати, і дізнатися з чого, використовуючи +перед будь-яким значенням JavaScript, перетворить це значення в число , але якщо це значення неможливо перетворити, двигун JavaScript поверне NaN , а це означає, а не число (не можна перетворіть номер, товариш!) та іншу частину історії, як показано нижче:

Чому результат ('b' + 'a' + + 'a' + 'a'). ToLowerCase () 'банан'?



Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.