Почему массивы длины 1 ведут себя как скаляры в JavaScript?

Пример:

let a = [1, 2]
console.info(a * 2);  // NaN, this isn't Python
a = [3];
console.info(a);  // an array, as expected: [3]
console.info(a * 2);  // 6!

Это бывает полезно на практике с объектами заголовков, которые обычно содержат массивы из 1 элемента:

// calculate when an API will reset its rate limit
new Date(response.headers['x-rate-limit-reset'] * 1000)

Но почему это работает?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
0
41
4

Ответы 4

Это потому, что во время умножения (*) происходит type conversion:

console.info(Number([1, 2])); // NaN

console.info(Number([2]));   // 2

ПРИМЕЧАНИЕ: перед преобразованием в тип Number JavaScript пытается преобразовать массив в String, что дает значения, разделенные запятыми, такие как '1,2' и '2'. Затем, когда JavaScript пытается преобразовать эту строку обратно в Number (потому что мы их умножаем), '1,2' дает NaN, тогда как '2' get конвертируется нормально.

Посмотреть на себя:

console.info(String([1,2]));   // '1,2' (of type string)
console.info(String([2]));     // '2' (of type string)
console.info(Number('1,2'));   // NaN (of type number)
console.info(Number('2'));     // 2 (of type number)

Для получения дополнительной информации см. это.

В самом деле, это можно даже расширить до большего количества уровней: console.info(Number([[[2]]])); // 2

Carsten Massmann 26.07.2018 09:57

Когда массив находится в выражении, в котором ожидается примитив, вызывается его метод toString. Для массивов это в основном arr.join(','). Строки, содержащие запятые, не могут быть преобразованы в числа:

let a = [1, 2]
console.info(a * 2);  // doesn't work
console.info('1, 2' * 2) // same string result: also doesn't work
console.info([1, 2].toString() === '1,2');

Но когда join(',') вызывается для массива с одним элементом, запятых нет, поэтому результат может должен быть преобразован в число и умножен на *.

console.info([3].toString());
console.info([3, 4].toString());
console.info(isNaN([3].toString()));
console.info(isNaN([3, 4].toString()));

Это связано с одинаковостью JavaScript.

Посетите эту страницу для получения полной документации: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness

Может случиться много автоматической конвертации :)

Вот странный / забавный:

console.info([1, 2] == '1,2')

Это объясняет:

console.info([6] == '6');
console.info([6] == 6);
console.info([6] * '7');

* - математический оператор, который пытается преобразовать все в числа! [6] можно преобразовать в 6 точно так же, как '7' можно преобразовать в 7, и вот оно!

Первый пример не странный. [1, 2] == '1,2' означает, что String([1,2]) == '1,2' зависит от типа обеих сторон.

Terry Wei 26.07.2018 10:04

Исчерпывающий ответ вы можете найти здесь: Официальная спецификация: ToNumber

Другие вопросы по теме