Hogyan működik az array.prototype.map ()

A JavaScript jelenleg mindenütt megtalálható nyelv. Ha egyszer csak az ügyféloldali használatra korlátozódott, most számos ízben megtalálhatja a szervereken. A JavaScript növekedésével a funkciók arzenálja is növekedett, amelyeket a felhasználók használhatnak. Legtöbbször megelégszik ezzel a módszerrel, és csak ritkán szeretné megtenni ezt a további lépést, hogy megértse, mi történik valójában a motorháztető alatt.

Ezen a megjegyzés, vessünk az extra lépést, ma és fedezze fel egy nagyon népszerű funkció: Array.prototype.map().

Jogi nyilatkozat : Nem fogom elmagyarázni, hogyan kell használni map()- az alábbi példa szemlélteti, vagy számos példát találhat, amikor google. Ehelyett vizsgáljuk meg, hogyan valósul meg a térkép a kulisszák mögött.

A map()módszer új tömböt hoz létre azzal az eredménnyel, hogy egy hívott tömb minden elemén meghív egy megadott függvényt.

Példa:

var array1 = [1, 4, 9, 16]; // pass a function to map const map1 = array1.map(x => x * 2); console.log(map1); // expected output: Array [2, 8, 18, 32]

Végrehajtás

Válasszuk ki a megvalósítást közvetlenül a ló szájából, és próbáljuk meg boncolgatni. Az alábbiakban látható az MDN polifill. Töltsön el egy kis időt a kód megértésével, másolja és futtassa a számítógépén. Ha Ön kezdő / középhaladó JavaScript-fejlesztő, akkor biztosan legalább néhány kérdésbe ütközik.

/*Array.prototype.map implementation*/ Array.prototype.map = function (callback/*, thisArg*/) { var T, A, k; if (this == null) { throw new TypeError('this is null or not defined'); } var O = Object(this); var len = O.length >>> 0; if (typeof callback !== 'function') { throw new TypeError(callback + ' is not a function'); } if (arguments.length > 1) { T = arguments[1]; } A = new Array(len); k = 0; while (k < len) { var kValue, mappedValue; if (k in O) { kValue = O[k]; mappedValue = callback.call(T, kValue, k, O); A[k] = mappedValue; } k++; } return A; };

Néhány általános kérdést kiemeltem, amelyek felmerülhetnek az alábbi kód megjegyzésekben.

/*Array.prototype.map implementation*/ Array.prototype.map = function (callback/*, thisArg*/) { var T, A, k; if (this == null) { throw new TypeError('this is null or not defined'); } var O = Object(this); var len = O.length >>> 0;// QUESTION 1 : What is the need for this line of code? if (typeof callback !== 'function') { throw new TypeError(callback + ' is not a function'); } if (arguments.length > 1) { T = arguments[1]; } // QUESTION 2 :What is the need for the if condition and why are we assiging T=arguments[1]? A = new Array(len); k = 0; while (k < len) { var kValue, mappedValue; if (k in O) { kValue = O[k]; mappedValue = callback.call(T, kValue, k, O); // QUESTION 3: why do we pass T,k and O when all you need is kvalue? A[k] = mappedValue; } k++; } return A; };

Nézzünk mindegyiket alulról kezdve

3. KÉRDÉS: Miért haladunk el T, k és O mellett, amikor csak a kValue szükséges?

mappedValue = callback.call(T, kValue, k, O);

Ez a három kérdés közül a legegyszerűbb, ezért ezt választottam kiindulásként. A legtöbb esetben elegendő a kValue átadása a visszahívásnak , de:

  • Mi van, ha van olyan felhasználási esete, amikor csak minden más elemet kell végrehajtania? Nos, szükséged van egy indexre, amely (k) .
  • Hasonlóképpen lehetnek más olyan esetek is, amikor szükség van arra, hogy maga a tömb (O) elérhető legyen a visszahívásban.
  • Miért T ? Egyelőre csak tudd, hogy T átkerül a kontextus fenntartásához. Ezt jobban meg fogja érteni, ha végzett a 2. kérdéssel.

2. KÉRDÉS: Mi szükség van az if feltételre, és miért rendelünk hozzá T = argumentumokat [1]?

if (arguments.length > 1) { T = arguments[1]; }

A fenti megvalósításban található térképfunkciónak két érve van: a visszahívás és az opcionális thisArg . A visszahívás kötelező érv, míg ez az argum opcionális.

A második opcionális argumentum megadásával átadhatjuk, hogy mi legyen a visszahívás „ez” értéke . Ezért a kód ellenőrzi, hogy több argumentum van-e, és a második opcionális argumentumot hozzárendeli egy változóhoz, amelyet tovább lehet adni a visszahívásnak.

A jobb szemléltetéshez tegyük fel, hogy van egy álkövetelményed, ahol vissza kell adnod a / 2 számot, ha osztható 2-vel, és ha nem osztható 2-vel, akkor vissza kell adnod a hívó személy felhasználónevét. Az alábbi kód bemutatja, hogyan lehet ezt megvalósítani:

const myObj = { user: "John Smith" } var x = [10, 7]; let output = x.map(function (n) { if (n % 2 == 0) { return n / 2; } else { return this.user } }, myObj) // myObj is the second optional argument arguments[1] console.log(output); // [5,'John Smith'] //if you run the program without supplying myObj it would be //undefined as it cannot access myObj values console.log(output); // [ 5, undefined ]

1. KÉRDÉS: Mi szükség van erre a kódsorra?

var len = O.length >>> 0

Ez eltartott egy ideig, mire rájöttem. Sok minden történik ebben a kódsorban. A JavaScript-ben újból meghatározhatja az „ezt” egy függvényen belül a hívást használó módszer meghívásával . Megteheti ezt a bind vagy az alkalmazással is, de ehhez a beszélgetéshez ragaszkodni kell a híváshoz.

const anotherObject={length:{}} const myObj = { user: "John Smith" } var x = [10, 7]; let output = x.map.call(anotherObject,function (n) { if (n % 2 == 0) {return n / 2;} else {return this.user} }, myObj)

Amikor hívással hívja meg,az első paraméter az a kontextus, amelyben a térképfüggvény végrehajtódik. Elküldésével paraméter, akkor felülírja az „ez” belül a térképen az „ez” a anotherObject.

Ha figyelembe, a hossza tulajdonsága anotherObject egy üres objektumot, és nem egész szám. Ha csak az O.hosszat használja az O.hossz> >> 0 helyett, akkor ez meghatározatlan értéket eredményez. A nulla eltolással valójában a törteket és a nem egész számokat egész számokká konvertálja. Ebben az esetben az eredmény 0-ra lesz kényszerítve.

A legtöbb használati esetben nem lesz szükség erre az ellenőrzésre, de előfordulhat olyan éles eset, amikor ezt a fajta forgatókönyvet kell kezelni. A specifikációt tervező jó programozók valóban átgondolták! Ha a specifikációról beszélünk, akkor az Ecmascriptben itt találhatja meg az egyes funkciók megvalósításának specifikációját:

ECMAScript nyelvi specifikáció - ECMA-262 kiadás 5.1

Ez a dokumentum és annak lehetséges fordításai másolhatók és átadhatók másoknak, valamint származékos művek, amelyek kommentálják…

www.ecma-international.org

A specifikáció ( 3. lépés ) egyértelműen kimondja, hogy a hossznak 32 bites előjel nélküli egész számnak kell lennie. Ez az oka annak, hogy nulla kitöltés változik annak biztosítása érdekében, hogy a hosszúság egész szám legyen, mivel a térkép önmagában nem követeli meg, hogy ez az érték tömb objektum legyen.

Ez az!

Szeretnék köszönetet mondani pár embernek, soha nem találkoztam velük, de voltak szívesek időt szánni (internetes fórumokon) és segítettek megérteni néhány árnyalatot.

Salathiel Genese, Jordan Harband - köszönöm!

Megjegyzés: Ha egy másik kódsorra ragadt, nyugodtan tegye ezt a megjegyzésekbe, és mindent megteszek a pontosítás érdekében.

Köszönjük az időt és a boldog kódolást!