ennek megértése, Bind, Call, and Apply in JavaScript

ennek megértése, Bind, Call, and Apply in JavaScript

Ez a cikk eredetileg a DigitalOcean számára készült.

athis kulcsszó nagyon fontos fogalom a JavaScriptben, és különösen zavaró mind az új fejlesztők, mind azok számára, akik tapasztalattal rendelkeznek más programozási nyelvekben. A JavaScript-ben a this egy objektumra való hivatkozás., Az objektum, amelyre this utal, implicit módon változhat attól függően, hogy globális, objektumon vagy konstruktorban van-e, és kifejezetten változhat a Function prototípus módszerek bind, call és apply.

bár this egy kicsit összetett téma, ez is az, amely akkor jelenik meg, amikor elkezdi írni az első JavaScript programokat., Akár egy elemet vagy eseményt próbál elérni a Dokumentumobjektum-modellben( DOM), osztályokat épít az objektumorientált programozási stílusban történő íráshoz, vagy a normál objektumok tulajdonságait és módszereit használja, akkor thistalálkozik.

ebben a cikkben megtudhatja, hogy mit jelent a this implicit módon a kontextus alapján, és megtanulja, hogyan kell használni a bind, call és apply kifejezetten határozza meg a thisértékét.,

Implicit kontextus

négy fő kontextus létezik, amelyekben a this értéke implicit módon következtethető:

  • a globális kontextus
  • egy objektumon belüli módszerként
  • egy függvény vagy osztály konstruktoraként
  • mint DOM eseménykezelő

globális

a globális kontextusban a this a globális objektumra utal. Ha böngészőben dolgozik ,a globális környezet window. Amikor a Node-ban dolgozol.js, a globális kontextus global.,

Megjegyzés: Ha még nem ismeri a JavaScript hatókörének fogalmát, kérjük, olvassa el a változók, hatókör és emelés megértését a JavaScriptben.

a példákhoz a kódot a böngésző fejlesztői Eszközkonzoljában fogja gyakorolni. Olvassa el, hogyan kell használni a JavaScript fejlesztői konzolt, ha nem ismeri a JavaScript kód futtatását a böngészőben.

Ha athis értékét más kód nélkül naplózza, látni fogja, hogy athis mire utal.,

console.log(this)
Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}

láthatjuk, hogy this window, amely a böngésző globális tárgya.

a változók, a hatókör és a JavaScript-ben történő emelés megértésében megtudta, hogy a függvényeknek saját kontextusuk van a változók számára. Kísértés lehet arra gondolni, hogy athis ugyanazokat a szabályokat követi egy függvényen belül, de nem. A felső szintű függvény továbbra is megtartja a globális objektum this hivatkozását.,

felső szintű függvényt írsz, vagy olyan függvényt, amely nem kapcsolódik semmilyen objektumhoz, mint ez:

function printThis() { console.log(this)}printThis()

Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}

még egy függvényen belül is, this a window vagy globális objektumra utal.

szigorú mód használata esetén azonban athis kontextusa a globális kontextus függvényén belülundefinedlesz.,

'use strict'function printThis() { console.log(this)}printThis()
undefined

általában biztonságosabb a szigorú mód használata a this valószínűségének csökkentése érdekében. Ritkán valaki a window objektumra szeretne hivatkozni a thishasználatával.

további információ A szigorú üzemmód, mi változik ettől kapcsolatos hibák, biztonsági, olvassa el a Szigorú mód dokumentációt MDN.,

egy objektum metódus

egy metódus egy objektum függvénye, vagy egy objektum által végrehajtható feladat. Egy módszer athis értéket használja az objektum tulajdonságaira való hivatkozáshoz.

"The United States of America was founded in 1776."

ebben a példában this ugyanaz, mint a america.

beágyazott objektumban athis a módszer aktuális objektum hatókörére utal. A következő példában this.symbola detailsobjektum details.symbol.,

"The symbol is the eagle and the currency is USD."

egy másik gondolkodásmód az, hogy a this a pont bal oldalán lévő objektumra utal, amikor egy módszert hív.

A Function Constructor

amikor a new kulcsszót használja, létrehoz egy konstruktor függvény vagy osztály példányát. Függvény konstruktorok voltak a szokásos módon inicializálni a felhasználó által definiált objektum előttclass szintaxis vezették be az ECMAScript 2015 Frissítés JavaScript., A megértés osztályok JavaScript, meg fogja tanulni, hogyan kell létrehozni egy függvény konstruktor és egy egyenértékű osztály konstruktor.

"The United States of America was founded in 1776."

ebben az összefüggésben a this most a Country példányához van kötve, amelyet a america állandó tartalmaz.

egy osztály konstruktor

egy osztály konstruktora ugyanúgy működik, mint egy függvény konstruktora. További információ a függvény konstruktorok és az ES6 osztályok közötti hasonlóságokról és különbségekről a JavaScript osztályok megértésében.,

this adescribe módszer aCountry példányára utal, amelyamerica.

"The United States of America was founded in 1776."

a Dom eseménykezelő

a böngészőben van egy speciális this eseménykezelők kontextusa. addEventListener, thisevent.currentTarget., Gyakrabban, mint nem, a fejlesztők egyszerűen csak a event.target vagy event.currentTarget szükséges a DOM elemeinek eléréséhez, de mivel a this referencia változások ebben az összefüggésben fontos tudni.

a következő példában létrehozunk egy gombot, szöveget adunk hozzá, majd csatoljuk a DOM-hoz. Amikor a this értékét naplózzuk az eseménykezelőn belül, akkor kinyomtatja a célt.,

<button>Click me</button>

miután beillesztette ezt a böngészőbe, megjelenik egy gomb, amely az oldalhoz van csatolva, amely azt mondja:”kattints rám”. Ha rákattint a gombra, akkor a<button>Click me</button> jelenik meg a konzolban, mivel a gombra kattintva naplózza az elemet, amely maga a gomb. Ezért, amint láthatja, athis a célzott elemre utal, amelyhez egy esemény hallgatót adtunk hozzá.,

Explicit kontextus

az összes korábbi példában athis értékét a kontextusa határozta meg—legyen az Globális, egy objektumban, egy épített függvényben vagy osztályban, vagy egy DOM eseménykezelőben. A call, apply vagy bind használatával azonban kifejezetten meghatározhatja, hogy a this mire kell hivatkoznia.,

nehéz pontosan meghatározni, hogy mikor kell használni acall,apply, vagybind, mivel ez a program kontextusától függ. bind különösen hasznos lehet, ha eseményeket szeretne használni egy osztály tulajdonságainak eléréséhez egy másik osztályon belül. Például, ha egy egyszerű játékot írsz, akkor a felhasználói felületet és az I/O-t egy osztályra oszthatod, a játék logikáját pedig egy másikra., Mivel a játék logikájának hozzáférnie kell a bemenethez, például a gombnyomással és a kattintással, érdemes bind az események eléréséhez a this értéke a játék logikai osztály.

a fontos rész az, hogy tudjuk, hogyan lehet meghatározni, hogy milyen objektum this utal, amelyre hallgatólagosan megteheti az előző szakaszokban tanultakkal, vagy kifejezetten a következő három módszerrel.,

hívja és alkalmazza

call és apply nagyon hasonlóak—olyan függvényre hivatkoznak, amelynek meghatározott this kontextusa és opcionális argumentuma van. Az egyetlen különbség a call és apply között az, hogy call az argumentumokat egyenként kell átadni, és apply az argumentumokat tömbként veszi át.,

ebben a példában létrehozunk egy objektumot, és létrehozunk egy függvényt, amely a this – ra hivatkozik, de nincs this kontextus.

"undefined was written by undefined"

mivel summary és book nincs kapcsolat, hivatkozva summary önmagában csak nyomtatni undefined, mivel ezeket a tulajdonságokat keresi a globális objektumon.,

Megjegyzés: ennek szigorú módban történő megkísérlése Uncaught TypeError: Cannot read property 'title' of undefined, mivel this maga lenne undefined.

azonban használhatja a call és apply hivatkozhat a this book / div > a funkció.,

summary.call(book)// or:summary.apply(book)
"Brave New World was written by Aldous Huxley."

most van egy kapcsolat a book és summary között, amikor ezeket a módszereket alkalmazzák. Erősítsük meg pontosan, hogy mi a this.

function printThis() { console.log(this)}printThis.call(book)// or:whatIsThis.apply(book)

ebben az esetben this valójában argumentumként átadott objektum lesz.

így vancall ésapply ugyanaz, de van egy kis különbség., Amellett, hogy képes átadni a this kontextust az első érvként, további érveket is átadhat.

function longerSummary(genre, year) { console.log( `${this.title} was written by ${this.author}. It is a ${genre} novel written in ${year}.`, )}

a call minden további érték, amelyet át szeretne adni, további argumentumként kerül elküldésre.,

longerSummary.call(book, 'dystopian', 1932)

"Brave New World was written by Aldous Huxley. It is a dystopian novel written in 1932."

ha pontosan ugyanazokat az érveket próbálja elküldeni aapply, ez történik:

longerSummary.apply(book, 'dystopian', 1932)

Uncaught TypeError: CreateListFromArrayLike called on non-object at <anonymous>:1:15

ehelyett aapply argumentumokat egy tömbben kell átadni.

longerSummary.apply(book, )
"Brave New World was written by Aldous Huxley. It is a dystopian novel written in 1932."

az érvek egyenként vagy egy tömbben történő átadása közötti különbség finom, de fontos, hogy tisztában legyünk vele., Egyszerűbb és kényelmesebb lehet a apply használata, mivel nem lenne szükség a függvényhívás megváltoztatására, ha néhány paraméter részlete megváltozott.

Bind

Both call és apply egyszeri használatú módszerek-ha a módszert a this kontextussal hívja, akkor ez lesz, de az eredeti funkció változatlan marad.,

néha előfordulhat, hogy egy másik objektum this kontextusával újra és újra kell használnia egy módszert, ebben az esetben a bind módszert használhatja egy teljesen új funkció létrehozásához, kifejezetten kötött this.

const braveNewWorldSummary = summary.bind(book)braveNewWorldSummary()
"Brave New World was written by Aldous Huxley"

ebben a példában minden alkalommal, amikor braveNewWorldSummary, mindig visszaadja az eredeti this div > érték kötődik hozzá., Az új this kontextus összekapcsolása sikertelen lesz,így mindig bízhat egy kötött függvényben, hogy visszaadja athis értéket.

bár ez a példa megpróbálja kötnibraveNewWorldSummary ismét, megtartja az eredetithis kontextust az első megkötéstől kezdve.

Arrow Functions

Arrow függvények nem rendelkeznek sajátthis kötés. Ehelyett a végrehajtás következő szintjére lépnek.,

hasznos lehet a nyíl funkció használata olyan esetekben, amikor valóban szeretné this hivatkozni a külső kontextusra. Például, ha volt egy esemény hallgató belsejében egy osztály, akkor valószínűleg szeretné this hivatkozni néhány értéket az osztályban.

ebben a példában a DOM-hoz hozzácsatolja a gombot, mint korábban, de az osztálynak van egy eseményhallgatója, amely megváltoztatja a gomb szövegértékét, amikor rákattint.

Ha rákattint a gombra, a szöveges tartalom a buttonTextértékre változik., Ha itt nem használt volna nyílfüggvényt, akkor a this egyenlő lenne a event.currentTarget értékkel, és nem tudná használni az osztályon belüli érték elérésére anélkül, hogy azt kifejezetten kötné. Ezt a taktikát gyakran használják osztálymódszereken olyan keretekben, mint a React.

Következtetés

ebben A cikkben, értesült this a JavaScript, a sok különböző értéke lehet alapuló implicit runtime kötelező, de kifejezett kötelező keresztül bind, call vagy apply., Azt is megtudta, hogy a this kötés hiánya a nyílfüggvényekben más kontextusra utalhat. Ezzel a tudással meg kell tudnia határozni a this értékét a programokban.

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük