Послушайте, я не думаю, что вам стоит читать о том, как правильно кодировать Javascript, от парня, который только его изучает.

Справедливости ради, я немного разбирался в Javascript здесь и там, и есть несколько языков, в которых я хорошо разбираюсь, но я только сейчас пытаюсь пройти учебный курс по разработке программного обеспечения. Я действительно все еще новичок в Javascript.

Тем не менее, одно из требований к моему Bootcamp — это:

Сообщение в блоге об этом этапе учебной программы.

И:

Блоги должны быть о техническом аспекте, связанном с Фазой учебной программы.



Итак, мы здесь.

И я собираюсь поговорить о углублении.

Одним из моих недавних заданий было воссоздание функций сбора, подобных этим методам экземпляра для массивов https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array.

Вот одна из функций, которые я должен был создать в этом задании:

мой первый

myFirst(array, [n])

Параметр(ы):

- массив

- целое число (необязательно)

Возвращаемое значение:

– Один элемент ИЛИ массив

Поведение:

Возвращает первый элемент array. Передача n вернет первые n элементов массива.



Мне показалось, что я должен использовать slice. Но slice создает неглубокую копию:

Все встроенные операции копирования массива (синтаксис распространения, Array.from(), Array.prototype.slice() и Array.prototype.concat()) создают мелкие копии. Если вместо этого вам нужна глубокая копия массива, вы можете использовать JSON.stringify() для преобразования массива в строку JSON, а затем JSON.parse() для преобразования строки обратно в новый массив, полностью независимый от исходного массива.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array#instance_methods

(Конечно, теперь, когда я пишу, я понимаю, что мог бы просто использовать splice, и проблема создания поверхностной копии исчезла бы… Но мы говорим о путешествии, а не пункт назначения, да?)

Если я верну неглубокую копию, возможно, я смогу пройти тесты https://github.com/learn-co-curriculum/phase-1-javascript-functional-library-project/blob/master/test/indexTest. js, но это все, о чем мне нужно беспокоиться? Прохождение испытаний? И, к вашему сведению, я случайно узнал, что неглубокая копия на самом деле прошла бы тесты, поскольку в итоге я представил это:

функция myFirst(массив, n=””) {

if (!n) {

возвращаемый массив[0]

}

вернуть массив.срез(0,n)

}

И прошло нормально.

Но внезапно мне задали много очень глубоких вопросов. Когда вы выходите за рамки требований? Когда вы пытаетесь внедрить решения для крайних случаев? И когда ты остановишься?

На самом деле, если подумать, даже если бы я получил сплайс, чтобы пройти тест, я бы модифицировал исходный массив, а это может быть нежелательно. На самом деле, я думаю, что читал в нескольких местах, что модифицировать или деструктировать, как правило, плохая практика, и вместо этого делать копии, когда это возможно, если только вас специально не просят или не нужно изменять.

Итак, я решил сделать глубокую копию, но разве вы не знаете, что даже JSON.Stringify() / JSON.Parse() не является гарантированной глубокой копией. Вот статья на Medium, тоже, вероятно, написанная каким-то дилетантом, которого заставляют писать так, как будто он знает, о чем говорит https://medium.com/@pmzubar/why-json-parse-json-stringify-is-a-bad -практика-клонирования-объекта-в-javascript-b28ac5e36521. (Шучу, я понятия не имею, кто этот парень, но статья определенно имеет высокий рейтинг в Google. Так что, вероятно, это не полная чушь.)

Хорошо, теперь мы видим, что клонирование путем преобразования и разбора JSON может вызвать огромные проблемы и стать антипаттерном. С тех пор есть лучшие подходы:

(самый простой) Используйте jQuery или Lodash реализации глубокого клонирования

(более интересно) Напишите свою собственную функцию глубокого клонирования, используя рекурсию (или просто погуглите, чтобы найти некоторые реализации).

Итак, я иду глубже в кроличью нору, чтобы посмотреть, как сделать более глубокую копию. JQuery и Lodash, вероятно, действительно противоречили бы духу этого упражнения. Если бы они хотели, чтобы мы использовали JQuery, который у меня есть в прошлом, а он тупо-простой по сравнению с Javascript, то они бы давно это сделали. И они, вероятно, правы, не вводя JQuery, потому что в прошлом я использовал его как костыль и в результате действительно мало узнал о Javascript.

Так что остается глубокая рекурсия клонирования. Когда вы ищете в Google функции рекурсии глубокого клонирования, оказывается, что надежных функций не существует.

Не согласен с ответом с наибольшим количеством голосов здесь. Рекурсивное глубокое клонирование намного быстрее, чем упомянутый подход JSON.parse(JSON.stringify(obj)).

А вот функция для быстрого ознакомления

ответил 18 июн 2017 в 6:34



Глядя на комментарии:

Мне понравился этот подход, но он неправильно обрабатывает даты; рассмотрите возможность добавления чего-то вроде if(o instanceof Date) return new Date(o.valueOf()); после проверки на null `

Луис

21 августа 2017 г., 22:53

Сбои при циклических ссылках.

Гарри

18 марта 2018 г., 5:19

И снова и снова я видел много подобных комментариев для функций глубокого рекурсивного глубокого клонирования в stackoverflow.

Теперь обратите внимание на даты в этих комментариях: 2017 и 2018. Ответ тоже из 2017. А эта статья на Медиуме? С 2019 года. Но главный ответ из того же stackoverflow был фактически отредактирован менее двух месяцев назад:

Нативное глубокое клонирование

В настоящее время существует стандарт JS под названием структурированное клонирование, который экспериментально работает в Node 11 и более поздних версиях, появится в браузерах и имеет полифиллы для существующих систем.

structuredClone(value)

При необходимости сначала загрузите полифилл:

import structuredClone from '@ungap/structured-clone';

Смотрите этот ответ для более подробной информации.

отредактировано 31 июл в 19:22

Ах ха! Я думаю. Решение! Я могу сделать глубокий клон. Я могу пройти тест И быть уверенным в будущем. Ура!

Бууууу… Ничто не бывает так просто.

О, Элис, ты так далеко зашла в кроличью нору, не могла бы ты на минутку оглянуться? Можете ли вы все еще видеть свет, если хотите выбраться? Или уже слишком поздно?

Я пытаюсь создать эту функцию:

функция myFirst(массив, n="")

{ if (!n) {

возвращаемый массив[0]

}

константный новый массив = []; для (пусть i = 0; i ‹ n; i++) {

const clone = структурированный клон (массив [i]);

новыймассив.push(клон);

}

вернуть новый массив

}

Но, подождите минутку, мой node.js не распознает «structuredClone».

Совместимость с браузером

Node.js

17.0.0



У меня версия 16.17.1. По-видимому, это самая последняя стабильная версия:

Загрузки

Последняя LTS-версия: 16.17.1 (включает npm 8.15.0)

https://nodejs.org/en/download/

Я дважды проверяю, что StructuredClone действительно работает в большинстве современных браузеров, и этого достаточно для меня (потому что, если мне придется беспокоиться о совместимости с IE 5, который, я почти уверен, получил несколько дополнительных ударов в сердце деревянным колом, чтобы быть в безопасности, когда они похоронили Internet Explorer… у меня проблемы посерьезнее). Так что я думаю, ладно, заставь его работать на моей машине, и все должно быть в порядке.

Теперь у меня нет проблем с установкой самой последней версии node.js. Это не похоже на передовую ночную сборку. Это просто не сверхбезопасная и сверхосторожная сборка, которую вы получаете по умолчанию. Но это означает, что мне нужно выяснить, как установить его на мою «Ubuntu для Windows», а из-за «для Windows» я здесь не в своей тарелке.

Но я все равно разбираюсь. Я запускаю несколько команд «sudo», которые заставляют меня немного попотеть, но в конце концов я заставляю их работать на моей машине…

Буууууууууууууууу, но тестовый скрипт все равно не проходит. Вероятно, потому что в тесте используется собственная версия node.js или что-то в этом роде. Но это не первая моя поездка в Страну Чудес. Я знаю, что мог бы, вероятно, понять это, по крайней мере, почему он не прошел тест. Но я также знаю, что это, вероятно, не стоит того в данный момент. Вероятно, пришло время просто пройти чертов тест и двигаться дальше.

(На самом деле, я только что понял, я, вероятно, мог бы использовать эту строку из ответа на stackoverflow:

import structuredClone from '@ungap/structured-clone';

Но если бы я мог импортировать это… Разве я не мог бы просто импортировать lodash? Опять же, в какой-то момент вам просто нужно двигаться дальше.)

Итак, в конечном счете, как я упоминал ранее, я отправляю:

функция myFirst(массив, n=””) {

if (!n) {

возвращаемый массив[0]

}

вернуть массив.срез(0,n)

}

И, как я уже говорил, проходит нормально.

Эти упражнения, они действительно странные. Вы не можете думать о том, для чего на самом деле предназначены эти упражнения, потому что это упражнения. Гипотезы, в общем. Вы не можете думать о своих «выходах», так как все это пустая трата времени. Так что все, что вы можете сделать, это думать о своей аудитории.

Кто ваша аудитория для этих упражнений? Чего они хотят?

И даже это непонятно.

Я даже не уверен, что кто-то увидит тот факт, что, несмотря на то, что я вставил вышеупомянутый код, я все же поставил перед ним этот комментарий (и да, он имеет указанную ниже ошибку в написании слова «фунцитон»):

// если требуется только неглубокая копия, работает функция без комментариев

// в противном случае работает функция с комментариями ниже, однако для StructuredClone требуется узел 17 или более поздний:

// https://developer.mozilla.org/en-US/docs/Web/API/structuredClone

// вероятно, поэтому он не прошел «тест обучения»

/*

функция myFirst(массив, n=””) {

if (!n) {

возвращаемый массив[0]

}

вернуть массив.срез(0,n)

}

*/

Итак… Чему я научился благодаря всему этому? На самом деле я довольно много узнал о поверхностных и глубоких копиях. Но что более важно, я прошел через довольно долгое испытание, которое может компенсировать пост в блоге. И, наконец, это всегда самое важное. Потому что это сообщение в блоге является обязательным. Я должен это сделать.

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

ПОСТ СЦЕНАРИЙ:

На самом деле, я, вероятно, тоже не должен был использовать slice.

Целью этого упражнения является создание собственной реализации методов обработки коллекции. Не используйте повторно встроенные методы!



Таким образом, большинство из этих функций были довольно ясны в отношении методов, которых мы должны были избегать. Как и функция «myEach», которую мы должны были создать. Ясно, что мы должны были сделать это без использования forEach. Довольно просто, подумал я. Только не используйте forEach, подумал я. Наверное, все остальное в порядке, подумал я.

Затем я подумал, что, может быть, мы должны воссоздать какой-нибудь метод, в котором есть слово «первый». Но я не мог придумать методы сбора со словом «первый». Так что думаю все есть! Но… «срез» по-прежнему является методом обработки коллекции… Это просто не часть имени функции, которую я должен создать…

О, ну, PTDC. (Пройденный тест Не волнует.)