Hakkerit JavaScript-taulukoiden luomiseen

Oivaltavia vinkkejä matriisien luomiseen ja kloonaamiseen JavaScriptissä.

Jokaisen ohjelmointikielen erittäin tärkeä näkökohta on kielellä käytettävissä olevat tietotyypit ja rakenteet. Useimmat ohjelmointikielet tarjoavat tietotyyppejä monimutkaisten tietojen edustamiseen ja käsittelyyn. Jos olet työskennellyt kielillä, kuten Python tai Ruby, sinun olisi pitänyt nähdä tietotyyppejä, kuten luetteloita , sarjoja , sarakkeita , hajautuksia , saneluita ja niin edelleen.

JavaScriptissä ei ole niin paljon monimutkaisia ​​tietotyyppejä - sinulla on vain taulukot ja objektit . ES6: ssa kielelle lisättiin kuitenkin muutama tietotyyppi ja rakenne, kuten symbolit , joukot ja kartat .

Taulukot JavaScriptissä ovat korkean tason luettelomaisia ​​objekteja, joilla on pituusominaisuus ja kokonaislukuominaisuudet indeksinä.

Tässä artikkelissa jaan pari hakkerointia uusien JavaScript-taulukoiden luomiseksi tai jo olemassa olevien kloonaamiseksi.

Taulukoiden luominen: Array Constructor

Suosituin menetelmä taulukoiden luomiseksi on taulukon kirjaimellisen syntaksin käyttö, mikä on hyvin suoraviivaista. Kuitenkin, kun haluat luoda dynaamisesti taulukoita, taulukon kirjainteksti ei aina ole paras tapa. Vaihtoehtoinen menetelmä on käyttää Arraykonstruktoria.

Tässä on yksinkertainen koodinpätkä, joka näyttää Arrayrakentajan käytön.

Edellisestä katkelmasta voimme nähdä, että Arraykonstruktori luo matriisit eri tavalla riippuen saamistaan ​​argumenteista.

Uudet taulukot: Määritetyn pituuden

Katsotaanpa tarkemmin, mitä tapahtuu, kun luot uuden Arraytietyn pituisen. Rakentaja asettaa vain lengthmatriisin ominaisuuden annetulle pituudelle asettamatta avaimia.

Yllä olevasta katkelmasta saatat joutua kiusaukseen ajatella, että taulukon jokaisen avaimen arvoksi on asetettu undefined. Mutta tosiasia on, että näitä avaimia ei koskaan asetettu (niitä ei ole).

Seuraava kuva tekee siitä selkeämmän:

Tämä tekee siitä hyödyttömän yrittää käyttää mitä tahansa taulukon iteraation menetelmillä, kuten map(), filter()tai reduce()manipuloida jono. Oletetaan, että haluamme täyttää matriisin jokaisen indeksin 5arvona arvona. Yritämme seuraavaa:

Voimme nähdä, että map()se ei toiminut täällä, koska indeksin ominaisuuksia ei ole taulukossa - vain lengthominaisuus on olemassa.

Katsotaanpa erilaisia ​​tapoja korjata ongelma.

1. Käyttämällä Array.prototype.fill ()

fill()Menetelmä täyttää kaikki elementit array peräisin alku indeksi päättyy indeksi staattinen arvo. Loppuhakemisto ei sisälly. Voit oppia lisää fill()täältä.

Huomaa, että se fill()toimii vain selaimissa, joissa on ES6-tuki.

Tässä on yksinkertainen kuva:

Tässä olemme pystyneet täyttämään kaikki luomamme taulukon elementit 5. Voit asettaa minkä tahansa staattisen arvon taulukon eri hakemistoille fill()menetelmällä.

2. Array.from () -ohjelman käyttö

Array.from()Menetelmä luo uuden, matala-kopioitu Arrayesimerkiksi matriisista kaltainen tai iterable esine. Voit oppia lisää Array.from()täältä.

Huomaa, että se Array.from()toimii vain selaimissa, joissa on ES6-tuki.

Tässä on yksinkertainen kuva:

Tässä on nyt undefinedasetettu tosi arvot jokaiselle matriisin elementille Array.from(). Tämä tarkoittaa, että voimme nyt mennä eteenpäin ja käyttää menetelmiä kuten .map()ja .filter()taulukossa, koska indeksin ominaisuudet ovat nyt olemassa.

Vielä yksi huomionarvoinen asia Array.from()on, että se voi viedä toisen argumentin, joka on karttatoiminto. Sitä kutsutaan matriisin jokaiselle elementille. Tämä tekee siitä tarpeettoman soittamisen .map()jälkeen Array.from().

Tässä on yksinkertainen esimerkki:

3. Levitysoperaattorin käyttö

Leviäminen operaattori( ...), joka on lisätty ES6: een, voidaan käyttää matriisin elementtien levittämiseen asettamalla puuttuvien elementtien arvoksi undefined. Tämä tuottaa saman tuloksen kuin yksinkertaisesti kutsuminen Array.from()vain taulukon kanssa ainoana argumenttina.

Tässä on yksinkertainen esimerkki levitysoperaattorin käytöstä:

Voit mennä eteenpäin ja käyttää menetelmiä, kuten .map()ja .filter()taulukossa, koska indeksin ominaisuudet ovat nyt olemassa.

Array.of (): n käyttäminen

Aivan kuten näimme luomalla uusia taulukoita käyttämällä Arraykonstruktoria tai funktiota, Array.of()käyttäytyy hyvin samalla tavalla. Itse asiassa ainoa ero Array.of()ja Arraysiihen, kuinka ne käsittelevät yhden kokonaisluku argumentti niihin.

Samalla kun Array.of(5)luodaan uusi matriisi, jossa on yksi elementti, 5ja pituus ominaisuus 1, Array(5)luo uuden tyhjän array 5 tyhjiä ja pituus ominaisuus 5.

var array1 = Array.of(5); // [5] var array2 = Array(5); // Array(5) {length: 5}

Tämän suuren eron lisäksi Array.of()käyttäytyy aivan kuten Arrayrakentaja. Voit oppia lisää Array.of()täältä.

Huomaa, että se Array.of()toimii vain selaimissa, joissa on ES6-tuki.

Muunnos taulukoiksi: Taulukko-tykkäykset ja Iterables

Jos olet kirjoittanut JavaScript-funktioita riittävän kauan, sinun tulisi jo tietää argumentsobjektista - joka on matriisimainen objekti, joka on käytettävissä jokaisessa toiminnossa, jotta se säilyttää funktion saaman argumenttilistan. Vaikka argumentsesine näyttää paljon matriisilta, sillä ei ole pääsyä Array.prototypemenetelmiin.

Ennen ES6: ta näet yleensä seuraavanlaisen koodinpätkän, kun yrität muuntaa argumentsobjektia matriisiksi:

Levitysoperaattorin Array.from()tai levitysoperaattorin avulla voit muuntaa minkä tahansa taulukon kaltaisen objektin kätevästi taulukoksi. Näin ollen sen sijaan, että tekisit tämän:

var args = Array.prototype.slice.call(arguments);

voit tehdä jommankumman näistä:

// Using Array.from() var args = Array.from(arguments); // Using the Spread operator var args = [...arguments];

Nämä koskevat myös iterableja seuraavan kuvan mukaisesti:

Tapaustutkimus: Alueen toiminta

Tapaustutkimuksena ennen jatkamista luomme yksinkertaisen range()toiminnon juuri oppimamme uuden matriisihakemuksen toteuttamiseksi . Toiminnolla on seuraava allekirjoitus:

range(start: number, end: number, step: number) => Array

Tässä on koodinpätkä:

Tässä koodinpätkässä käytimme Array.from()uuden dynaamisen pituisen aluejoukon luomista ja sitten sen lisäämistä peräkkäin kasvaviin numeroihin tarjoamalla kartoitusfunktion.

Huomaa, että yllä oleva koodinpätkä ei toimi selaimissa, joissa ei ole ES6-tukea, paitsi jos käytät polyfill-täytteitä.

Tässä on joitain tuloksia range()yllä olevassa koodinpätkässä määritetyn toiminnon kutsumisesta :

Saat live- koodidemon suorittamalla seuraavan kynän Codepenissä :

Kloonausjärjestelmät: Haaste

JavaScriptissä taulukot ja objektit ovat viitetyyppejä. Tämä tarkoittaa, että kun muuttujalle määritetään taulukko tai objekti, muuttujalle määritetään viittaus muistin sijaintiin, johon taulukko tai objekti on tallennettu.

Taulukot, kuten kaikki muutkin JavaScript-objektit, ovat viitetyyppejä. Tämä tarkoittaa, että taulukot kopioidaan viitteenä eikä arvona.

Tällä tavalla viitetyyppien tallentamisella on seuraavat seuraukset:

1. Samanlaiset taulukot eivät ole yhtä suuria.

Tässä näemme, että vaikka array1ja array2sisältävät ilmeisesti sama joukko tekniset tiedot, ne eivät ole samanarvoisia. Tämä johtuu siitä, että viittaus kullekin matriisista osoittaa eri sijainnin muistissa.

2. Taulukot kopioidaan viitteiden eikä arvojen mukaan.

Täällä yritämme kopioida array1ja array2, mutta mitä me pohjimmiltaan teemme osoittaa array2samaan paikkaan muistissa että array1pistettä. Siksi molemmat array1ja array2osoittavat samaan paikkaan muistissa ja ovat yhtä suuria.

Tämän seurauksena on, että kun teemme muutoksen array2poistamalla viimeisen kohteen, myös sen viimeinen kohde array1poistetaan. Tämä johtuu siitä, että muutos tehtiin todellisuudessa muistiin tallennetulle ryhmälle, kun taas array1ja array2ovat vain viitteitä samaan muistin sijaintiin, johon taulukko on tallennettu.

Kloonausjärjestelmät: Hacks

1. Käyttämällä Array.prototype.slice ()

slice()Menetelmä luo matala kopio osasta joukko muuttamatta jono. Voit oppia lisää slice()täältä.

Temppu on kutsua slice()joko 0ainoana argumenttina tai ilman mitään argumentteja:

// with O as only argument array.slice(0); // without argument array.slice();

Tässä on yksinkertainen esimerkki ryhmän kloonaamisesta slice():

Täällä voit nähdä, että array2on klooni, array1jolla on samat kohteet ja pituus. Ne osoittavat kuitenkin muistin eri paikkoihin, eivätkä ne ole sen vuoksi samanarvoisia. Huomaa myös, että kun teemme muutoksen array2poistamalla viimeisen kohteen, se array1pysyy muuttumattomana.

2. Array.prototype.concat () -ohjelman käyttö

concat()Menetelmää käytetään yhdistää kaksi tai useampia taulukoita, tuloksena on uusi joukko, kun taas alkuperäinen ryhmät eivät muutu. Voit oppia lisää concat()täältä.

Temppu on kutsua concat()joko tyhjällä taulukolla ( []) argumenttina tai ilman mitään argumentteja:

// with an empty array array.concat([]); // without argument array.concat();

Taulukon kloonaaminen concat()on melko samanlainen kuin käyttö slice(). Tässä on yksinkertainen esimerkki ryhmän kloonaamisesta concat():

3. Käyttämällä Array.from ()

Kuten aiemmin näimme, Array.from()sitä voidaan käyttää uuden taulukon luomiseen, joka on matala kopio alkuperäisestä taulukosta. Tässä on yksinkertainen kuva:

4. Taulukon uudelleenjärjestelyn käyttäminen

ES6: n avulla työkalupakissa on joitain tehokkaampia työkaluja, kuten tuhoaminen , levittäminenoperaattori , nuolitoiminnot ja niin edelleen. Uudelleenjärjestely on erittäin tehokas työkalu tietojen keräämiseen monimutkaisista tyypeistä, kuten matriisista ja objekteista.

Temppu on käyttää tekniikkaa , jota kutsutaan lepoparametreiksi, johon kuuluu taulukon hajotuksen ja levitysoperaattorin yhdistelmä seuraavan katkelman mukaisesti:

let [...arrayClone] = originalArray;

Yllä oleva katkelma luo muuttujan nimeltä nimeltä, arrayClonejoka on originalArray. Tässä on yksinkertainen esimerkki taulukon kloonaamisesta käyttämällä taulukon uudelleenjärjestelyä:

Kloonaus: matala vs. syvä

Kaikki tähän mennessä tutkimamme matriisikloonaustekniikat tuottavat matalan kopion matriisista. Tämä ei ole ongelma, jos taulukko sisältää vain primitiivisiä arvoja. Jos matriisi kuitenkin sisältää sisäkkäisiä objektiviittauksia, nämä viitteet pysyvät ehjinä, vaikka taulukko kloonattaisiin.

Tässä on hyvin yksinkertainen osoitus tästä:

Huomaa, että sisäkkäisen taulukon muokkaaminen array1modifioi myös sisäkkäistä taulukkoa array2ja päinvastoin.

Ratkaisu tähän ongelmaan on luoda syvällinen kopio taulukosta, ja tähän on olemassa pari tapaa.

1. JSON-tekniikka

Helpoin tapa luoda syvällinen kopio taulukosta on käyttää yhdistelmää JSON.stringify()ja JSON.parse().

JSON.stringify()muuntaa JavaScript-arvon kelvolliseksi JSON-merkkijonoksi, kun taas JSON.parse()JSON-merkkijono vastaavaksi JavaScript-arvoksi tai objektiksi.

Tässä on yksinkertainen esimerkki:

JSON-tekniikalla on joitain puutteita varsinkin kun kyseessä ovat muut arvot kuin merkkijonot, numerot ja loogiset arvot.

Nämä JSON-tekniikan puutteet voidaan pääasiassa liittää tapaan, jolla JSON.stringify()menetelmä muuntaa arvot JSON-merkkijonoksi.

Tässä on yksinkertainen osoitus tästä virheestä yrittäessä JSON.stringify()sisäkkäistä toimintoa sisältävää arvoa.

2. Syvä kopioinnin auttaja

Elinkelpoinen vaihtoehto JSON-tekniikalle on toteuttaa oma syväkopio-aputoiminto kloonaamaan viitetyypit riippumatta siitä, ovatko ne matriisit tai objektit.

Tässä on hyvin yksinkertainen ja minimalistinen syväkopiointitoiminto nimeltä deepClone:

Nyt tämä ei ole paras syväkopiointitoiminto siellä, kuten näet pian joidenkin JavaScript-kirjastojen kanssa - se tekee kuitenkin syvää kopiointia melko hyvin.

3. JavaScript-kirjastojen käyttäminen

Äskettäin määrittelemämme syväkopiointitoiminto ei ole riittävän vahva kloonattaessa kaikenlaisia ​​JavaScript-tietoja, jotka voivat olla sisäkkäisiä monimutkaisissa kohteissa tai matriiseissa.

JavaScript-kirjastot, kuten Lodash ja jQuery, tarjoavat vankemmat syväkopiointitoiminnot ja tuen erilaisille JavaScript-tiedoille.

Tässä on esimerkki, joka käyttää _.cloneDeep()Lodash-kirjastosta:

Tässä on sama esimerkki, mutta $.extend()jQuery-kirjastosta:

Johtopäätös

Tässä artikkelissa olemme pystyneet tutkimaan useita tekniikoita uusien taulukoiden luomiseksi dynaamisesti ja jo olemassa olevien kloonaamiseksi, mukaan lukien taulukon kaltaisten objektien ja iteraaalien muuntaminen matriiseiksi.

Olemme myös nähneet, kuinka jotkut ES6: ssa esitetyistä uusista ominaisuuksista ja parannuksista voivat auttaa meitä suorittamaan tiettyjä manipulaatioita matriiseihin.

Ryhmien kloonaamiseen ja levittämiseen käytimme ominaisuuksia, kuten hajotusta ja levitysoperaattoria. Tästä artikkelista saat lisätietoja rakenneuudistuksesta.

Taputa ja seuraa

Jos löysit tämän artikkelin oivaltavaksi, voit vapaasti antaa suosionosoituksia, jos et välitä.

Voit myös seurata minua Mediumissa (Glad Chinda) saadaksesi hyödyllisiä artikkeleita. Voit myös seurata minua Twitterissä (@gladchinda).

Hyvää hakkerointia ...