Инициализация цикла For с несколькими разными типами данных [duplicate]

У меня есть два хороших ответа в зависимости от того, должна ли ваша цель клонировать «простой старый объект JavaScript» или нет.

Предположим также, что вы намерены создать полный клон без ссылок на прототипы назад к исходному объекту. Если вас не интересует полный клон, вы можете использовать многие из подпрограмм Object.clone (), предоставленные в некоторых других ответах (шаблон Крокфорда).

Для простых старых объектов JavaScript надежный и надежный способ клонирования объекта в современных средах выполнения довольно просто:

var clone = JSON.parse(JSON.stringify(obj));

Обратите внимание, что исходный объект должен быть чистым объектом JSON. Это означает, что все его вложенные свойства должны быть скалярами (например, логическими, строковыми, массивными, объектными и т. Д.). Любые функции или специальные объекты, такие как RegExp или Date, не будут клонированы.

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

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

Теперь, для не-простых объектов JavaScript, нет простого ответа. На самом деле не может быть из-за динамического характера функций JavaScript и состояния внутреннего объекта. Глубокое клонирование структуры JSON с функциями внутри требует, чтобы вы воссоздали эти функции и их внутренний контекст. И JavaScript просто не имеет стандартного способа сделать это.

Правильный способ сделать это еще раз - это метод удобства, который вы декларируете и повторно используете в своем коде. Метод удобства может быть наделен некоторым пониманием ваших собственных объектов, чтобы вы могли правильно воссоздать график в новом объекте.

Мы пишем наш собственный, но лучший общий подход. см. здесь:

http://davidwalsh.name/javascript-clone

Это правильная идея. Автор (Дэвид Уолш) прокомментировал клонирование обобщенных функций.

Основная идея заключается в том, что вам нужно специально обработать инстанцирование ваших функций (или прототипных классов, если можно так выразиться) тип основы. Здесь он предоставил несколько примеров для RegExp и Date.

Этот код не только краткий, но и очень читабельный. Это довольно легко расширить.

Это эффективно? Черт возьми. Учитывая, что цель состоит в том, чтобы создать настоящий клон с глубокой копией, вам придется ходить по членам графа исходного объекта. С помощью этого подхода вы можете точно настроить, какие дочерние элементы обрабатывать и как вручную обрабатывать настраиваемые типы.

Итак, вы идете. Два подхода. На мой взгляд, обе эффективны.

77
задан Ciro Santilli 新疆改造中心 六四事件 法轮功 26 February 2015 в 08:36
поделиться

4 ответа

Вам это не понравится. Либо вы используете несколько переменных одного и того же типа for(Object var1 = null, var2 = null; ...), либо вы извлекаете другую переменную и объявляете ее перед циклом for.

14
ответ дан Colin Hebert 21 August 2018 в 19:18
поделиться

Инициализация оператора for следует правилам для объявлений локальных переменных .

Это было бы законным (если глупо):

for (int a = 0, b[] = { 1 }, c[][] = { { 1 }, { 2 } }; a < 10; a++) {
  // something
}

Но попытка объявить различные Node и int типы, которые вам нужны, не является законной для локальных объявлений переменных.

Вы можете ограничить область дополнительных переменных внутри используя этот блок:

{
  int n = 0;
  for (Object o = new Object();/* expr */;/* expr */) {
    // do something
  }
}

Это гарантирует, что вы случайно не используете повторную переменную в другом месте метода.

89
ответ дан McDowell 21 August 2018 в 19:18
поделиться
  • 1
    Кто-нибудь знает, почему разработчики языка внедрили это, казалось бы, ненужное ограничение? – Jeff Axelrod 5 May 2011 в 16:44
  • 2
    @glenviewjeff - это было бы лучше спросить как отдельный вопрос. – McDowell 5 May 2011 в 22:17
  • 3
    @JeffAxelrod, возможно, по историческим причинам, потому что Java была смоделирована после C ++ ... см. Этот пост: stackoverflow.com/questions/2687392/… – Christophe Roussy 3 July 2013 в 10:58
  • 4
    +1 для использования блока, я использую их много, еще лучше, чем делать глупые ошибки – Christophe Roussy 3 July 2013 в 11:00

Просто переместите объявления переменных (Node<T> current, int currentIndex) за пределы цикла, и он должен работать. Что-то вроде этого

int currentIndex;
Node<T> current;
for (current = first; current != null; current = current.next, currentIndex++) {

или, может быть, даже

int currentIndex;
for (Node<T> current = first; current != null; current = current.next, currentIndex++) {
6
ответ дан Nikita Rybak 21 August 2018 в 19:18
поделиться
  • 1
    Не скомпилируется: перед использованием вы должны инициализировать переменные. – unbeli 22 August 2010 в 20:06
  • 2
    @unbeli хорошо, я не тренировался в ручной компиляции кода :) Я просто хотел дать эту идею. – Nikita Rybak 22 August 2010 в 20:30
  • 3
    @unbeli: Просто уточнить: currentIndex необходимо инициализировать. Первое, что делает Никита, это «currentIndex ++», который, естественно, поднимает вопрос, увеличивайте что? ток - это хорошо, потому что первое использование - установить его первым. – Jay 27 August 2010 в 18:22
  • 4
    @Jay да да да – unbeli 27 August 2010 в 20:59
  • 5
    Отсутствует инициализация, добавленная через edit ... – Chucky 1 March 2013 в 12:23
0
ответ дан Vishnu Prasanth G 4 November 2018 в 16:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: