Запутанный оператор запятой в JavaScript. Почему это так работает?

Может ли кто-нибудь объяснить, почему вывод кода

var a = [1,2];
console.info("Array item: " + a[a=a.toString(), 1]);
console.info("String char: " + a[1]);

как это выглядит?

Array item: 2                                                                   
String char: , 

Вопрос в том, почему массив не преобразовался в строку в первом console.info. Как в этом случае работают память и указатели?

Я обычно вижу этот вопрос, когда люди не знают оператора запятой. В этом случае я не понимаю, что вас смущает, можете ли вы уточнить, что вы ожидали от этого?

ASDFGerte 20.07.2018 17:59

Это в значительной степени "1,2"[1,2], а затем "1,2"[1]

Reinstate Monica Cellio 20.07.2018 18:04

@archer нет, скорее [1, 2]["1,2", 1] а потом "1,2"[1]

Jonas Wilms 20.07.2018 18:08

Вопрос в том, почему массив не преобразовался в строку в первом console.info. Как в этом случае работают память и указатели?

Tetyana 20.07.2018 18:30
Поведение ключевого слова "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) для оценки ваших знаний,...
1
5
51
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

a[a = a.toString(), 1] сначала оценивает a, который еще указывает на массив, затем заменяет a на строковый a, который не влияет на уже оцененную часть, затем обращается к индексу 1 массива. Это то же самое, что:

var b = a;
a.toString();
b[1]

Теперь a[1] оценивается как ,, потому что a теперь указывает на строку и, следовательно, получает второй символ.

Вот как это видит парсер:

a[a = a.toString(), 1]
// Evaluation of a
[1, 2][a = a.toString(), 1]
// Evaluation of the comma operator, a is turned into a string
[1, 2][1]
// Prop access
2

Не могли бы вы нарисовать простую схему с памятью и указателями, чтобы объяснить это?

Tetyana 20.07.2018 18:32

@tetyana, конечно, но я не думаю, что диаграммы облегчают задачу.

Jonas Wilms 20.07.2018 18:36

Я заметил, что вы редактировали комментарий, теперь я понимаю, как это работает. Диаграмма не требуется. Большое спасибо!

Tetyana 20.07.2018 18:43

@tetyana рада помочь :)

Jonas Wilms 20.07.2018 18:50

Вы сталкиваетесь с порядком оценки, порядком доступа и тем, как память хранит значения.

Javascript, как и другие языки, оценивается справа налево, хотя оператор запятой оценивает первый a=a.toString() в памяти, a равен [1,2], потому что самое правое значение будет оцениваться первым перед изменением переменной a, поэтому a[1] = 2.

После этого доступа переменная a равна "1,2" и a[1] = ,, в памяти String похожа на массив символов, и к ней можно получить доступ с помощью индексов.

Вот как происходит доступ:

          +------------+-------------+
          | Var a      | Access      |
          +------------+-------------+
       +--|    [1,2]   | a[1] -> 2   |-+---> This is the first access.
Memory |  +--------+-----------------+ |<--- Here the first value no longer exists and now a = String.
       +--|    "1,2"   | a[1] -> "," |-+---> This is the second access.
          +--------+-----------------+

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