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 this
talá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ülundefined
lesz.,
'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 this
haszná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.symbol
a details
objektum 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
, this
event.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
, mivelthis
maga lenneundefined
.
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.