Для кожнага па масіве ў JavaScript?

Як я магу праглядзець усе запісы ў масіве з дапамогай JavaScript?

Я падумаў, што гэта нешта накшталт гэтага:

 forEach(instance in theArray) 

Дзе theArray - мой масіў, але гэта здаецца няправільным.

4041
17 февр. зададзены Dante1986 17 февр. 2012-02-17 16:51 '12 у 16:51 2012-02-17 16:51
@ 32 адказаў
  • 1
  • 2

TL; DR

  • Не выкарыстоўвайце for-in калі вы не выкарыстоўваеце яго з абаронай або, па меншай меры, не ведаеце, чаму ён можа вас ўкусіць.
  • Вашыя лепшыя стаўкі звычайна

    • for-of Loop (толькі для ES2015 +),
    • Array#forEach ( spec | MDN ) (або яго сваякі some і такія) (толькі ES5 +),
    • просты старамодны for цыклы,
    • ці for-in ўваходу з абаронай.

Але ёсць яшчэ шмат, каб даследаваць, чытаць далей ...


JavaScript мае магутную семантыку для цыклічнага пераўтварэнні масіваў і аб'ектаў тыпу масіва. Я падзяліў адказ на дзве часткі: варыянты для сапраўдных масіваў і варыянты для рэчаў, якія падобныя толькі на масівы, такія як аб'ект arguments , іншыя итерируемые аб'екты (ES2015 +), калекцыі DOM і г.д.

Я хутка заметлю, што цяпер вы можаце выкарыстоўваць опцыі ES2015, нават на рухавіках ES5, шляхам перасылкі ES2015 на ES5. Знайдзіце "ES2015 transpiling" / "ES6 transpiling" для больш ...

Добра, паглядзім на нашы варыянты:

Для рэальных масіваў

У вас ёсць тры варыянты ў ECMAScript 5 ( "ES5"), версія, найбольш шырока падтрымліваецца на дадзены момант, і яшчэ дзве дададзеныя ў ECMAScript 2015 ( "ES2015", "ES6"):

  1. Выкарыстоўваць forEach і звязаныя з ім (ES5 +)
  2. Выкарыстоўвайце просты for цыклу
  3. Правільна выкарыстоўваць for-in
  4. Выкарыстоўваць for-of (выкарыстоўваць итератор няяўна) (ES2015 +)
  5. Выкарыстоўваць итератор відавочна (ES2015 +)

дэталі:

1. Выкарыстоўваць forEach і звязаныя з ім

У любой няпэўна сучаснай асяроддзі (так, а не ў IE8), дзе ў вас ёсць доступ да функцый Array дададзеным ES5 (наўпрост ці з выкарыстаннем полиполнений), вы можаце выкарыстоўваць forEach ( spec | MDN ):

 var a = ["a", "b", "c"]; a.forEach(function(entry) { console.log(entry); }); 

forEach прымае функцыю зваротнага выкліку і, неабавязкова, значэнне, якое выкарыстоўваецца як this пры выкліку гэтага зваротнага выкліку (не выкарыстоўваецца вышэй). Зваротны выклік выклікаецца для кожнага запісу ў масіве, каб прапусціць неіснуючыя запісы ў разрэджаных масівах. Хоць я выкарыстаў толькі адзін аргумент вышэй, зваротны выклік выклікаецца з трыма: значэнне кожнай запісы, індэкс гэтым запісы і спасылка на масіў, які вы паўтараеце (у выпадку, калі ваша функцыя яшчэ не мае яго).

Калі вы не падтрымліваеце састарэлыя браўзэры, такія як IE8 (якія NetApps паказвае на ўзроўні больш за 4% рынку на момант напісання гэтага артыкула ў верасні 2016 гады), вы можаце з радасцю выкарыстоўваць forEach на універсальнай вэб-старонцы без пракладкі. Калі вам трэба падтрымліваць састарэлыя браўзэры, лёгка выканаць аперацыю shimming / polyfilling forEach (знайдзіце "es5 shim" для некалькіх опцый).

forEach мае тое перавага, што вам не трэба аб'яўляць індэксаванне і зменныя значэння ў вобласці змесціва, паколькі яны пастаўляюцца ў якасці аргументаў функцыі ітэрацыі і настолькі добра арыентаваны на гэтую ітэрацыю.

Калі вы турбуецеся аб выдатках часу выканання выкліку функцыі для кожнага запісу масіву, не будзьце; падрабязнасці .

Акрамя таго, forEach - гэта функцыя "loop through them all", але ES5 вызначыў некалькі іншых карысных "прапрацовак праз функцыі масіва і рэчаў", у тым ліку:

  • every (спыняе цыкл у першы раз, калі зваротны выклік вяртае false ці нешта ілжывае)
  • some (спыняе цыкл у першы раз, калі зваротны выклік вяртае true ці нешта праўдападобнае)
  • filter (стварае новы масіў, які ўключае элементы, у якіх функцыя фільтра вяртае true і апускае тыя, дзе яна вяртае false )
  • map (стварае новы масіў з значэнняў, якiя вяртаюцца зваротным выклікам)
  • reduce (нарошчвае значэнне, паўторна выклікаючы зваротны выклік, перадаючы папярэднія значэнні, гл. спецыфікацыю для дэталяў, карысна для падсумоўвання змесціва масіва і многіх іншых рэчаў)
  • reduceRight (напрыклад, reduce , але працуе ў сыходным, а не ўзыходзячай парадку)

2. Выкарыстоўвайце просты for цыклу

Часам старыя спосабы з'яўляюцца лепшымі:

 var index; var a = ["a", "b", "c"]; for (index = 0; index < a.length; ++index) { console.log(a[index]); } 

Калі даўжыня масіва не будзе мяняцца на працягу цыклу, і яго прадукцыйнасць адчувальнага кода (малаверагодна), ледзь больш складаны варыянт захопу даўжынёй фронту можа быць ледзь - ледзь хутчэй:

 var index, len; var a = ["a", "b", "c"]; for (index = 0, len = a.length; index < len; ++index) { console.log(a[index]); } 

І / або лічачы назад:

 var index; var a = ["a", "b", "c"]; for (index = a.length - 1; index >= 0; --index) { console.log(a[index]); } 

Але з сучаснымі механізмамі JavaScript вам рэдка даводзіцца выкопваць гэты апошні сок.

У ES2015 і вышэй вы можаце зрабіць свой індэкс і зменныя значэнняў лакальнымі for цыклу for :

 let a = ["a", "b", "c"]; for (let index = 0; index < a.length; ++index) { let value = a[index]; } //console.log(index); // Would cause "ReferenceError: index is not defined" //console.log(value); // Would cause "ReferenceError: value is not defined" 

І калі вы гэта робіце, не толькі value але і index ўзнаўляюцца для кожнай ітэрацыі цыклу, то ёсць замыкання, створаныя ў тэгу цыклу, ўтрымліваюць спасылку на indexvalue ), створаны для гэтай канкрэтнай ітэрацыі:

 let divs = document.querySelectorAll("div"); for (let index = 0; index < divs.length; ++index) { divs[index].addEventListener('click', e => { alert("Index is: " + index); }); } 

Калі ў вас было пяць div, вы б атрымалі "Index is: 0", калі вы націснулі першы і "Index is: 4", калі вы націснулі апошні. Гэта не працуе, калі вы выкарыстоўваеце var замест let .

3. Правільна выкарыстоўвайце for-in

Вы атрымаеце людзі, якія распавядаюць вам выкарыстоўваць for-in , але гэта не тое , што for-in для . for-in запішуцца праз перечислимые ўласцівасці аб'екта, а не індэксы масіва. Заказ не гарантуецца, нават у ES2015 (ES6). ES2015 робіць вызначыць парадак уласцівасцяў аб'екта (з дапамогай [[OwnPropertyKeys]] , [[Enumerate]] , і рэчы, якія выкарыстоўваюць іх як Object.getOwnPropertyKeys ), але ён не вызначае, што for-in будзе прытрымлівацца, што замова. (Падрабязнасці ў гэтай другой адказе .)

Тым не менш, гэта можа быць карысна, асабліва для разрэджаных масіваў , калі вы выкарыстоўваеце адпаведныя меры засцярогі:

 // 'a' is a sparse array var key; var a = []; a[0] = "a"; a[10] = "b"; a[10000] = "c"; for (key in a) { if (a.hasOwnProperty(key)  // These are explained /^0$|^[1-9]\d*$/.test(key)  // and then hidden key <= 4294967294 // away below ) { console.log(a[key]); } } 

Звярніце ўвагу на дзве праверкі:

  1. Тое, што аб'ект мае сваё ўласнае ўласцівасць пад гэтым імем (а не той, які ён атрымлівае ў спадчыну ад свайго прататыпа), і

  2. Тое, што ключ ўяўляе сабой лікавую радок base-10 у сваёй звычайнай радковыя форме, і яе значэнне <= 2 ^ 32 - 2 (што складае 4 294 967 294). Адкуль гэты лік? Гэта частка вызначэння індэкса масіва ў спецыфікацыі . Іншыя ліку (нецелых колькасці, адмоўныя лікі, лікі больш 2 ^ 32 - 2) не з'яўляюцца індэксамі масіва. Прычынай 2 ^ 32 - 2 з'яўляецца тое, што робіць найбольшае значэнне індэкса менш за 2 ^ 32 - 1, што з'яўляецца максімальным значэннем length масіва. (Напрыклад, даўжыня масіва адпавядае 32-разрадных цэламу ліку без знака.) (Пацвярджэнне на RobG для ўказанні ў каментары да майго паведамлення ў блогу, што мой папярэдні тэст быў не зусім мае рацыю).

Гэта малюсенькі біт дадатковых накладных расходаў для кожнай ітэрацыі цыклаў на большасці масіваў, але калі ў вас ёсць разрэджаны масіў, гэта можа быць больш эфектыўным спосабам для цыклу, таму што гэта толькі цыклы для запісаў, якія на самай справе існуюць. Напрыклад, для масіва вышэй, мы зацыклівацца тры разы (для клавіш "0" , "10" і "10000" - памятаеце, гэта радкі), а не 10 001 разоў.

Зараз вы не захочаце пісаць гэта кожны раз, так што вы можаце змясціць гэта ў свой інструментар:

 function arrayHasOwnIndex(array, prop) { return array.hasOwnProperty(prop)  /^0$|^[1-9]\d*$/.test(prop)  prop <= 4294967294; // 2^32 - 2 } 

І тады мы будзем выкарыстоўваць яго так:

 for (key in a) { if (arrayHasOwnIndex(a, key)) { console.log(a[key]); } } 

Ці, калі вас цікавіць толькі тэст "дастаткова добры для большасці выпадкаў", вы можаце выкарыстоўваць гэта, але пакуль яно блізка, гэта не зусім правільна:

 for (key in a) { // "Good enough" for most cases if (String(parseInt(key, 10)) === key  a.hasOwnProperty(key)) { console.log(a[key]); } } 

4. Выкарыстоўвайце for-of (выкарыстоўвайце итератор няяўна) (ES2015 +)

ES2015 дадае итераторы да JavaScript. Самы просты спосаб выкарыстання итераторов - гэта новы аператар for-of . Гэта выглядае так:

 var val; var a = ["a", "b", "c"]; for (val of a) { console.log(val); } 

выснову:

 a b c

Пад вокладкамі, які атрымлівае итератор з масіва і праходзіць праз яго, атрымлівае значэння з яго. У гэтага няма праблемы, звязанай з выкарыстаннем for-in , паколькі ён выкарыстоўвае итератор, пэўны аб'ектам (масівам), а масівы вызначаюць, што іх итераторы паўтараюць свае запісы (а не іх ўласцівасці). У адрозненне ад for-in ў ES5, парадак, у якім праглядаюцца запісу, уяўляе сабой лікавы парадак іх індэксаў.

5. Выкарыстоўвайце итератор відавочна (ES2015 +)

Часам вы можаце відавочна выкарыстоўваць итератор. Вы таксама можаце гэта зрабіць, хоць гэта нашмат clunkier чым for-of . Гэта выглядае так:

 var a = ["a", "b", "c"]; var it = a.values(); var entry; while (!(entry = it.next()).done) { console.log(entry.value); } 

Итератор - гэта аб'ект, які адпавядае вызначэнню Iterator ў спецыфікацыі. Яго next метад вяртае новы аб'ект выніку кожны раз, калі вы яго выклікаеце. Аб'ект result мае ўласцівасць, done , паведамляе нам, ці было гэта зроблена, і value ўласцівасці са значэннем для гэтай ітэрацыі. ( done неабавязкова, калі яно было б false , value з'яўляецца неабавязковым, калі яно не undefined ).

Значэнне value вар'іруецца ў залежнасці ад итератора; масівы падтрымліваюць (прынамсі) тры функцыі, якія вяртаюць итераторы:

  • values() : Гэта той, які я выкарыстаў вышэй. Ён вяртае итератор, дзе кожнае value ўяўляе сабой запіс масіва для гэтай ітэрацыі ( "a" , "b" і "c" у прыкладзе раней).
  • keys() : Вяртае итератор, дзе кожнае value з'яўляецца ключавым для гэтай ітэрацыі (так што для нашай вышэй, што будзе a "0" , а затым "1" , а затым "2" ).
  • entries() : вяртае итератор, дзе кожнае value ўяўляе сабой масіў у форме [key, value] для гэтай ітэрацыі.

Для аб'ектаў, падобных масіву

Акрамя сапраўдных масіваў, існуюць таксама падобныя масіву аб'екты, якія маюць ўласцівасць length і ўласцівасці з лікавымі імёнамі: асобнікі NodeList , аб'ект arguments і г.д. Як мы NodeList іх змесціва?

Выкарыстоўвайце любы з вышэйпералічаных параметраў для масіваў

Па меншай меры некаторыя і, магчыма, большасць ці нават усе з вышэйпералічаных масіваў часта прымяняюцца аднолькава добра для аб'ектаў тыпу масіва:

  1. Выкарыстоўваць forEach і звязаныя з ім (ES5 +)

    Розныя функцыі на Array.prototype з'яўляюцца "наўмысна генерычных" і звычайна могуць выкарыстоўвацца для аб'ектаў, падобных масіву, з дапамогай Function#call Function#apply або Function#apply . (Гл. Агаворкамі для аб'ектаў, прадстаўленых хастом, у канцы гэтага адказу, але гэта рэдкая праблема.)

    Выкажам здагадку, вы хацелі выкарыстоўваць forEach ў childNodes Node childNodes . Вы зрабілі б гэта:

     Array.prototype.forEach.call(node.childNodes, function(child) { // Do something with 'child' }); 

    Калі вы збіраецеся зрабіць гэта шмат, вы можаце захацець атрымаць копію спасылкі на функцыю ў зменнай для паўторнага выкарыстання, напрыклад:

     // (This is all presumably in some scoping function) var forEach = Array.prototype.forEach; // Then later... forEach.call(node.childNodes, function(child) { // Do something with 'child' }); 
  2. Выкарыстоўвайце просты for цыклу

    Відавочна, просты цыкл for ўжываецца да аб'ектаў, падобным масіву.

  3. Правільна выкарыстоўваць for-in

    for-in з тымi ж гарантыямi, што і з масівам, павінен працаваць і з падобнымі масіву аб'ектамі; можа спатрэбіцца агаворка для аб'ектаў, прадстаўленых хастом, на № 1 вышэй.

  4. Выкарыстоўваць for-of (выкарыстоўваць итератор няяўна) (ES2015 +)

    for-of будзе выкарыстоўваць итератор, які прадстаўляецца аб'ектам (калі такі маецца); мы павінны будзем ўбачыць, як гэта адбываецца з рознымі падобнымі масівам аб'ектамі, асабліва з хост файламі. Напрыклад, спецыфікацыя для NodeList ад querySelectorAll была абноўлена для падтрымкі ітэрацыі. Спецыфікацыю для HTMLCollection з getElementsByTagName не было.

  5. Выкарыстоўваць итератор відавочна (ES2015 +)

    См. № 4, нам трэба паглядзець, як разгортваюцца итераторы.

Стварыць праўдзівы масіў

У іншых выпадках вы можаце пераўтварыць аб'ект, падобны масіву, у праўдзівы масіў. Рабіць гэта на здзіўленне лёгка:

  1. Выкарыстоўваць метад slice масіваў

    Мы можам выкарыстоўваць метад slice масіваў, які, як і іншыя метады, згаданыя вышэй, з'яўляецца "наўмысна агульным" і таму можа выкарыстоўвацца з падобнымі масіву аб'ектамі, напрыклад:

     var trueArray = Array.prototype.slice.call(arrayLikeObject); 

    Так, напрыклад, калі мы хочам пераўтварыць NodeList ў сапраўдны масіў, мы маглі б зрабіць гэта:

     var divs = Array.prototype.slice.call(document.querySelectorAll("div")); 

    См. "Засцярога для аб'ектаў, якія прадстаўляюцца хастом" ніжэй. У прыватнасці, звярніце ўвагу, што гэта не атрымаецца ў IE8 і раней, што не дазваляе выкарыстоўваць аб'екты, прадастаўленыя хастом, як this .

  2. Выкарыстоўваць сінтаксіс распаўсюду ( ... )

    Таксама магчыма выкарыстоўваць сінтаксіс распаўсюджвання ES2015 з механізмамі JavaScript, якія падтрымліваюць гэтую функцыю:

     var trueArray = [...iterableObject]; 

    Так, напрыклад, калі мы хочам пераўтварыць NodeList ў праўдзівы масіў, з сінтаксісам распаўсюджвання гэта становіцца даволі кароткім:

     var divs = [...document.querySelectorAll("div")]; 
  3. Выкарыстоўвайце Array.from (spec) | (MDN)

    Array.from (ES2015 +, але лёгка полі запоўнены) стварае масіў з аб'екта, падобнага масіву, пры неабходнасці спачатку перадаючы запісу праз функцыю супастаўлення. так:

     var divs = Array.from(document.querySelectorAll("div")); 

    Ці, калі вы хочаце атрымаць масіў імёнаў тэгаў для элементаў з зададзеным класам, вы павінны выкарыстоўваць функцыю параўнання:

     // Arrow function (ES2015): var divs = Array.from(document.querySelectorAll(".some-class"), element => element.tagName); // Standard function (since 'Array.from' can be shimmed): var divs = Array.from(document.querySelectorAll(".some-class"), function(element) { return element.tagName; }); 

Перасцярога для аб'ектаў, якія прадстаўляюцца хастом

Калі вы выкарыстоўваеце функцыі Array.prototype з аб'ектамі, падобнымі хастам (спісы DOM і іншыя рэчы, якія прадстаўляюцца браўзэрам, а не рухавічком JavaScript), вы павінны быць упэўнены, што будзеце тэставаць ў сваіх мэтавых асяроддзях, каб пераканацца, што выдзелены хост аб'ект паводзіць сябе правільна. Большасць з іх вядуць сябе правільна (цяпер), але важна праверыць. Прычына ў тым, што большасць метадаў Array.prototype якія вы, верагодна, захочаце выкарыстоўваць, належаць на прадастаўлены хастом аб'ект, даючы сумленны адказ на абстрактную [[HasProperty]] . На момант напісання гэтага артыкула браўзэры вельмі добра справіліся з гэтым, але спецыфікацыя 5.1 дазволіла выказаць здагадку, што аб'ект, які прадстаўляецца хастом, можа быць не сумленным. Гэта ў §8.6.2 , некалькі абзацаў ніжэй вялікі табліцы ў пачатку гэтага падзелу), дзе гаворыцца:

Хост-аб'екты могуць рэалізоўваць гэтыя ўнутраныя метады любым спосабам, калі не пазначана іншае; напрыклад, адна магчымасць заключаецца ў тым, што [[Get]] і [[Put]] для пэўнага аб'екта хаста сапраўды здабываюць і захоўваюць значэння уласцівасцяў, але [[HasProperty]] заўсёды генеруюць false.

(Я не мог знайсці эквівалентную фармулёўку ў ES2015 спецыфікацыі, але ён абавязаны яшчэ быць.) Зноў жа, як гэта напісаннем агульных хаста які прадастаўляецца масіва тыпу аб'ектаў у сучасных браўзэрах [ NodeList асобнікаў, напрыклад] зрабіць ручка [[HasProperty]] правільна, але важна праверыць.)

6292
17 февр. адказ дадзены TJ Crowder 17 февр. 2012-02-17 16:53 '12 у 16:53 2012-02-17 16:53

Змяніць: гэты адказ безнадзейна састарэў. Для больш сучаснага падыходу паглядзіце на метады, даступныя ў масіве . Цікавяць метады могуць быць:

  • для кожнага
  • карта
  • фільтр
  • зашпілька-маланка
  • паменшыць
  • кожны
  • трохі

Стандартны спосаб ітэрацыі масіва ў JavaScript - гэта ваніль for -loop:

border=0
 var length = arr.length, element = null; for (var i = 0; i < length; i++) { element = arr[i]; // Do something with element } 

Звярніце ўвагу, аднак, што гэты падыход добры, толькі калі ў вас шчыльны масіў, і кожны індэкс заняты элементам. Калі масіў разрэджаны, то пры такім падыходзе вы можаце сутыкнуцца з праблемамі прадукцыйнасці, так як вы будзеце перабіраць мноства індэксаў, якія на самай справе не існуюць у масіве. У гэтым выпадку лепш выкарыстаць for.. in -loop. Але Вам трэба будзе выкарыстоўваць адпаведныя меры засцярогі, каб гарантаваць, што будуць дзейнічаць толькі патрабаваныя ўласцівасці масіва (гэта значыць элементы масіва), паколькі for..in -loop таксама будзе пералічвацца ў састарэлых браўзэрах, або калі дадатковыя ўласцівасці вызначаны як enumerable .

У ECMAScript 5 для прататыпа масіва будзе выкарыстоўвацца метад forEach, але ён не падтрымліваецца ў састарэлых браўзэрах. Таму, каб мець магчымасць выкарыстоўваць яго паслядоўна, вы павінны альбо мець сераду, якая яго падтрымлівае (напрыклад, Node.js для сервернага JavaScript), альбо выкарыстоўваць "Polyfill". Polyfill для гэтай функцыянальнасці, аднак, трывіяльны, і, паколькі ён робіць код больш лёгкім для чытання, яго варта ўключыць у Polyfill.

470
17 февр. адказ дадзены PatrikAkerstrand 17 февр. 2012-02-17 16:55 '12 У 16:55 2012-02-17 16:55

Калі вы выкарыстоўваеце бібліятэку jQuery , вы можаце выкарыстоўваць jQuery.each :

 var length = yourArray.length; for (var i = 0; i < length; i++) { // Do something with yourArray[i]. } 
214
17 февр. адказ дадзены Poonam 17 февр. 2012-02-17 17:01 '12 у 17:01 2012-02-17 17:01

цыкл назад

Я думаю, што адваротнае для цыклу заслугоўвае згадвання тут:

 for (var i = array.length; i--; ) { // process array[i] } 

перавагі:

  • Вам не трэба аб'яўляць часовую зменную len або параўноўваць яе з array.length на кожнай ітэрацыі, якая можа быць хвіліннай аптымізацыяй.
  • Выдаленне братоў / сясцёр з DOM ў зваротным парадку звычайна больш эфектыўна. (Браўзэр неабходна менш перамяшчаць элементы ва ўнутраных масівах.)
  • Калі вы змяняе масіў падчас цыкла, у або пасля індэкса я (напрыклад, вы выдаляеце або ўстаўляеце элемент у array[i] ), тады прамой цыкл прапускае элемент, які ссунуты налева ў становішча я ці пераправерыць i-й элемент, які быў ссунуты направа. У традыцыйным цыкле вы можаце абнавіць i, каб паказаць на наступны элемент, які мае патрэбу ў апрацоўцы - 1, але проста змяніць кірунак ітэрацыі часта прасцей і больш элегантнае рашэнне .
  • Аналагічна, пры змене або выдаленні ўкладзеных элементаў DOM апрацоўка ў зваротным парадку можа абыходзіць памылкі. Напрыклад, разгледзіце магчымасць змены innerHTML бацькоўскага node перад апрацоўкай яго даччыных элементаў. Да моманту дасягнення даччынага элемента node ён будзе аддзелены ад DOM, замяніўшы яго новым нашчадкам, калі быў запісаны бацькоўскі innerHTML.
  • карацей, і прачытаць, чым некаторыя іншыя даступныя опцыі. Хоць ён губляе да forEach() і да ES6 for ... of .

недахопы:

  • Ён апрацоўвае элементы ў зваротным парадку. Калі вы будавалі новы масіў з вынікаў або друкавалі на экране, натуральна выснова будзе адменены адносна зыходнага парадку.
  • Неоднократно вставляя братьев и сестер в DOM в качестве первого ребенка, чтобы сохранить их порядок, менее эффективен . (В браузере все равно придется перекладывать вещи.) Чтобы создавать узлы DOM эффективно и упорядоченно, просто переходите вперед и добавьте как обычно (а также используйте "фрагмент документа" ).
  • Обратный цикл запутывает для младших разработчиков. (Вы можете считать это преимущество, в зависимости от вашего прогноза.)

Должен ли я всегда использовать его?