Пустой массив или усечение length = 0

Привет всем! Делаю функцию, которая бы разбивала текст на равные куски по 70 символов и записывала бы в 2-мерный массив, остаток букв просто добавляется ещё одним массивом в массив. Заметил интересный факт (строка 17): если обнулять массив line для новой итерации как line = [], то всё работает, как нужно. Но если сделать это через line.length = 0; что, как мне казалось, одно и то же, получается абы что - на выходе массив, состоящий из последних букв, которые “в остатке”. Почему такая разница? Чего я не догоняю? Пробовал отслеживать line.length в процессе цикла, как прирастает line - всё адекватно. Но вот как итоговый массив lines - абы что… Уже сломал бошку

let text = `Равным образом сложившаяся структура организации позволяет выполнять важные задания по разработке системы обучения кадров, соответствует насущным потребностям. С другой стороны дальнейшее развитие различных форм деятельности в значительной степени обуславливает создание систем массового участия. Идейные соображения высшего порядка, а также реализация намеченных плановых заданий обеспечивает широкому кругу (специалистов) участие в формировании модели развития. Товарищи! постоянный количественный рост и сфера нашей активности требуют определения и уточнения модели развития.`;

const input = document.querySelector("input"),
      textExample = document.querySelector(".text");

let letterNumber = 1;

function divideIntoLines(text) {
  const line = [];
  const lines = [];

  for (let i = 0; i < text.length; i++) {
    line.push(text[i]);

    if(line.length >= 70 || text[i] === "\n") {
      lines.push(line);
      line.length = 0;
    }
  }

  if(line.length > 0) {
    lines.push(line);
  }

  return lines;
}

divideIntoLines(text);

Приложи и текст кода пожалуйста. Работать со скришотом очень муторно.

Хорошо, сделал )

1 лайк

Тут фишка в том что line на протяжении всех циклов - ссылка на один и тот же массив. В lines вставляется один и тот же line (в терминах js - ссылка на один и тот же массив). Ты наполняешь line данными, вставляешь в массив а потом обнуляешь line.length, и получается что вставленный массив пуст. На следующей итерации повторяются те же самые шаги, приводящие к тому что в lines line вставлен дважды.

В целом когда генерируешь сложные структуры данных, обращай внимание что все вложенные ссылочные типы данных (объекты-массивы) создаются заново, и не переиспользуются.

Почитать дальше по теме:
https://learn.javascript.ru/object-reference
Ключевые слова для гугления “по ссылке и по значению”

Да, я знаю, что объекты передаются по ссылке. Но разве lines[ i ] продолжает ссылаться на line? Мне казалось, что после того, как значение line стало элементом lines, то обнуление длины line не должно влиять на lines… Или lines содержит по итогу ссылки на line, а не сами объекты??

Это более точное описание. Точнее сказать будет “line и lines[1] ссылаются на один и тот же объект”.

Демонстрация этого концепта. Добавляем ссылку на объект дважды, модифицирует объект по ссылке, получаем что оба добавления содержат изменения.

// утилита
function clone(obj) {
	return JSON.parse(JSON.stringify(obj))
}

const a = []
const b = []
b.push(a)
console.log(clone(b)) // делаем клон и смотрим на него
b.push(a)
console.log(clone(b))
a.push(1)
console.log(clone(b))

Дмитрий, можно я подытожу? :)
Итак, в функции в куче создаётся массив, ссылку на который я кладу в переменную line. В процессе цикла этот массив заполняется символами и, когда их становится 70, то в массиве lines создаётся первый элемент lines[0], в который передается ссылка на содержащий 70 символов массив в куче. Т.е. lines[0] и line сейчас ссылаются на один и тот же массив в куче из 70 символов. Потом я делаю line.length = 0. И в итоге lines[0] === []. Так происходит на всех итерациях цикла, пока набирается 70 символов. Как только их меньше - срабатывает последнее условие и в lines попадает только 1 массив с остатком букв. Теперь правильно?

Все в точку

1 лайк