Ar neteisinga naudoti tą patį kintamojo pavadinimą keliais ciklais?

Aš tiesiog atkreipiau javascript kodą naudojant jshint. Kode aš turiu dvi kilpas, kurios naudojamos taip:

 for (var i = 0; i < somevalue; i++) { ... } 

Taigi abu kontūrus naudoti var iteracijai.

Dabar „JSHint“ parodo klaidą antroji kilpa: „„ i “jau apibrėžta“. Negaliu pasakyti, kad tai neteisinga (nes tai akivaizdu), bet aš visada maniau, kad tai nesvarbu, nes aš naudoju tik var šioje konkrečioje vietoje.

Ar tai yra bloga praktika naudoti tokias linijas? Pvz., Turėčiau naudoti kitą kintamąjį kiekvienam savo kodo kilpui

 //for-loop 1 for (var i = 0; ...; i++) { ... } //for-loop 2 for (var j = 0; ...; j++) { ... } 

Ar tai yra dėl klaidų, kurias galiu ignoruoti (nes ji nepažeidžia mano kodo, ji vis dar daro tai, ką turėtų daryti)?

JSLint btw. nustoja tikrinti pirmoje kilpoje, nes nenurodau varo funkcijos viršuje (todėl pirmiausia perjungiau į JSHint). Taigi, pagal šio klausimo pavyzdį: Ar turėčiau naudoti JSLint patvirtinimą arba „JSHint JavaScript“? - noriu patvirtinti JSLint, turiu naudoti tokias kilpas:

 ... var i; ... //for-loop 1 for (i = 0; ...; i++) { ... } ... //for-loop 2 for (i = 0; ...; i++) { ... } 

Tai taip pat atrodo gerai man, nes tokiu būdu turiu vengti klaidų JSLint ir JSHint. Bet aš nesu įsitikinęs, ar aš naudosiu kitą kintamąjį kiekvienam for-loop'ui:

 ... var i, j; ... //for-loop 1 for (i = 0; ...; i++) { ... } //for-loop 2 for (j = 0; ...; j++) { ... } 

Taigi, ar tai yra geriausia praktika, ar galiu tik eiti su vienu iš pirmiau minėtų kodų, o tai reiškia, kad aš pasirenku „gerąją“ praktiką?

54
03 апр. nustatė TimG 03 Bal. 2013-04-03 12:09 '13, 12:09, 2013-06-03 12:09
@ 6 atsakymai

Kadangi kintamosios deklaracijos kyla į tos srities viršūnę, kurioje jie rodomi, vertėjas veiksmingai interpretuos abi versijas taip pat. Dėl šios priežasties „JSHint“ ir „JSLint“ siūlo skelbimų perkėlimą iš kontūro iniciatoriaus.

Šis kodas ...

 for (var i = 0; i < 10; i++) {} for (var i = 5; i < 15; i++) {} 

... yra veiksmingai aiškinama taip:

 var i; for (i = 0; i < 10; i++) {} for (i = 5; i < 15; i++) {} 

Atkreipkite dėmesį, kad tikrai yra tik viena deklaracija i ir kelios užduotys - negalite „pakeisti“ kintamojo toje pačioje srityje.

Jei norite atsakyti į jūsų klausimą ...

Ar tai yra geriausia praktika, ar galiu eiti su bet kuriuo iš pirmiau minėtų kodų?

Yra įvairių nuomonių apie tai, kaip geriausiai tai padaryti. Asmeniškai sutinku su JSLint ir manau, kad kodas yra aiškesnis, kai deklaruojate visus kintamuosius kiekvienos srities viršuje. Kadangi kodas bus aiškinamas, kodėl gi ne rašyti kodą, kuris atrodo taip, kaip jis elgiasi?

Tačiau, kaip pastebėjote, kodas veiks nepriklausomai nuo pasirinkto požiūrio, todėl tai yra stiliaus / konvencijos pasirinkimas, ir jūs galite naudoti bet kokią formą, kurią jums labiausiai patinka.

55
03 апр. James Allardice atsakymas 03 d 2013-04-03 12:11 '13, 12:11, 2013-04-03 12:11

Kintamieji javascript yra taikymo sritis (apimtis).

Kai apibrėžiate var i kilpoje, jis lieka ten kilpoje, taip pat funkcija, turinti šią kilpą.

Žr. Žemiau.

 function myfun() { //for-loop 1 for (var i = 0; ...; i++) { ... } // i is already defined, its scope is visible outside of the loop1. // so you should do something like this in second loop. for (i = 0; ...; j++) { ... } // But doing such will be inappropriate, as you will need to remember // if `i` has been defined already or not. If not, the `i` would be global variable. } 
5
03 апр. Atsakymas duotas Jashwant 03 balandžio. 2013-04-03 12:12 '13, 12:12 2013-14-03 12:12

Žinau, kad į šį klausimą buvo atsakyta, bet jei norite, kad ciklas būtų super, parašykite juos taip:

 var names = ['alex','john','paul','nemo'], name = '', idx = 0, len = names.length; for(;idx<len;++idx) { name = names[idx]; // do processing... } 

Keli čia vykstantys dalykai ...

  • Masyvo ilgis saugomas „ len . Tai sustabdo JS, įvertindamas names.length

  • idx prieaugis yra PRE-INCREMENT (pvz., ++ idx NOT idx ++). Preliminarūs prieaugiai yra spartesni nei pokytis.

  • Išsaugoti nuorodą į name . Tai yra neprivaloma, tačiau rekomenduojama, jei name kintamąjį naudojate daug. Kiekvienam names[idx] reikia masyvo indekso paieškos. Ar ši paieška yra tiesinė paieška, medis ar maišos lentelė, paieška vis dar vykdoma. Todėl, norėdami sumažinti paiešką, išsaugokite nuorodą į kitą kintamąjį.

Galiausiai, tai yra tik mano asmeniniai pageidavimai, ir aš neturiu jokių įrodymų ar jokių pranašumų. Tačiau visada norėčiau inicijuoti tokio tipo kintamuosius, kuriuos jie, pvz., Atstovaus. name = '', .

5
19 нояб. AlexMorley-Finch atsakymas lapkričio 19 d 2013-11-19 14:28 '13, 14:28, 2013-11-19 14:28

Priežastis, kodėl JSHint rodo klaidą, yra tai, kad JS srityje funkcijos ir kintamos deklaracijos yra padidintos iki funkcijos pradžios.

„Firefox“ galite naudoti let raktinį žodį, kad apibrėžtumėte blokavimo sritį, tačiau šiuo metu ją nepalaiko kitos naršyklės.

let raktinis žodis yra įtrauktas į ECMAScript 6 specifikaciją.

4
03 апр. Atsakymas pateikiamas Corneliu 03 Bal. 2013-04-03 12:12 '13, 12:12 2013-14-03 12:12

Tai paminėta tik @TSCrowder komentare : jei jūsų aplinka ją palaiko (Firefox, Node.js), ES6 galite naudoti let skelbimą

 //for-loop 1 for (let i = 0; ...; i++) { ... } //for-loop 2 for (let i = 0; ...; i++) { ... } 

riboja taikymo sritį . Premija: JSHint nustoja skundą.

4
04 апр. atsakymą pateikė serv-inc 04 Bal 2016-04-04 10:20 '16 at 10:20 2016-04-04 10:20

Geriausia praktika yra sumažinti kintamųjų taikymo sritį, todėl geriausias būdas deklaruoti ciklų iteracijos kintamąjį

 //for-loop 1 for (var i = 0; ...; i++) { ... } //for-loop 2 for (var j = 0; ...; j++) { ... } 

Žinau, kokie kintamieji yra deklaruoti su var , bet aš perskaičiau kodo įskaitomumą.

1
03 апр. atsakymą pateikė Nikolajus Kostovas 03 balandžio. 2013-04-03 12:11 '13, 12:11, 2013-04-03 12:11

Žr. Kitus klausimus apie „ etiketes „ arba „ Užduoti klausimą“