A JavaScript-ben minden függvénynek van egy this
referenciája, amelyet automatikusan létrehoz, amikor deklarálja.
A JavaScript-ek this
meglehetősen hasonlítanak this
más osztályalapú nyelvek, például a Java vagy a C # referenciáihoz (a JavaScript prototípus-alapú nyelv és nincs „osztály” fogalom): Arra mutat, hogy melyik objektum hívja a függvényt (ezt az objektumot néha hívják) mint kontextus ). A JavaScript-ben azonban a this
függvényeken belüli hivatkozás különböző objektumokhoz köthető, attól függően, hogy hol hívják a függvényt .
Íme 5 alapvető szabály a this
kötelező bekötésre a JavaScript-ben:
1. szabály
Ha egy függvényt globális hatókörben hívnak meg, a this
hivatkozás alapértelmezés szerint a globális objektumhoz van kötve ( window
a böngészőben vagy global
a Node.js-ben). Például:
function foo() { this.a = 2; } foo(); console.log(a); // 2
Megjegyzés: Ha nyilvánítja a foo()
funkciót fenti szigorú módban, akkor hívja ezt a funkciót globális hatókörű, this
lesz undefined
és feladat this.a = 2
fog dobni Uncaught TypeError
kivétel.
2. szabály
Vizsgáljuk meg az alábbi példát:
function foo() { this.a = 2; } const obj = { foo: foo }; obj.foo(); console.log(obj.a); // 2
Nyilvánvaló, hogy a fenti kód, a foo()
funkció kerül meghívásra a összefüggésben van obj
tárgy és this
referencia most van kötve obj
. Tehát amikor egy függvényt egy kontextus objektummal hívunk meg, a this
hivatkozás ehhez az objektumhoz lesz kötve.
3. szabály
.call
, .apply
és .bind
mindezek felhasználhatók a hívás helyén kifejezett kötéshez this
. A használata .bind(this)
olyasmi, amit meglehetősen sok React komponensben láthat.
const foo = function() { console.log(this.bar) } foo.call({ bar: 1 }) // 1
Itt van egy rövid példa arra, hogyan használják mindegyiket a kötéshez this
:
.call()
:fn.call(thisObj, fnParam1, fnParam2)
.apply()
:fn.apply(thisObj, [fnParam1, fnParam2])
.bind()
:const newFn = fn.bind(thisObj, fnParam1, fnParam2)
4. szabály
function Point2D(x, y) { this.x = x; this.y = y; } const p1 = new Point2D(1, 2); console.log(p1.x); // 1 console.log(p1.y); // 2
Amit észre kell venni, az a kulcsszóval Point2D
meghívott függvény new
, és a this
hivatkozás p1
objektumhoz van kötve . Tehát amikor egy függvényt new
kulcsszóval hívnak meg , új objektumot hoz létre, és a this
hivatkozás ehhez az objektumhoz lesz kötve.
Megjegyzés: Amint egy függvényt new
kulcsszóval hívunk, konstruktor függvényként is hívjuk .
5. szabály
A JavaScript this
az aktuális kontextus alapján határozza meg a futásidejű értéket . Tehát this
néha másra is rámutathat, mint amire számít.
Tekintsük ezt a Cat osztály példáját egy úgynevezett módszerrel makeSound()
, követve a fenti 4. szabály mintáját konstruktor függvény és new
kulcsszó segítségével.
const Cat = function(name, sound) { this.name = name; this.sound = sound; this.makeSound = function() { console.log( this.name + ' says: ' + this.sound ); }; } const kitty = new Cat('Fat Daddy', 'Mrrooowww'); kitty.makeSound(); // Fat Daddy says: Mrrooowww
Most próbáljuk meg adni a macskának az utat az annoy()
emberek számára úgy, hogy fél másodpercenként egyszer megismételjük a hangját.
const Cat = function(name, sound) { this.name = name; this.sound = sound; this.makeSound = function() { console.log( this.name + ' says: ' + this.sound ); }; this.annoy = function() { let count = 0, max = 100; const t = setInterval(function() { this.makeSound(); // <-- this line fails with `this.makeSound is not a function` count++; if (count === max) { clearTimeout(t); } }, 500); }; } const kitty = new Cat('Fat Daddy', 'Mrrooowww'); kitty.annoy();
Ez nem működik, mert a setInterval
visszahíváson belül létrehoztunk egy új kontextust globális hatókörrel, így this
már nem mutatunk a cicás példányunkra. A webböngészőben this
ehelyett a Windows objektumra mutat, amelynek nincs makeSound()
metódusa.
Pár módszer a működéshez:
- Az új kontextus létrehozása előtt rendeljen
this
hozzá egy helyi nevű változóhozme
, vagyself
, vagy bármilyen más néven hívja, és használja ezt a változót a visszahíváson belül.
const Cat = function(name, sound) { this.name = name; this.sound = sound; this.makeSound = function() { console.log( this.name + ' says: ' + this.sound ); }; this.annoy = function() { let count = 0, max = 100; const self = this; const t = setInterval(function() { self.makeSound(); count++; if (count === max) { clearTimeout(t); } }, 500); }; } const kitty = new Cat('Fat Daddy', 'Mrrooowww'); kitty.annoy();
- Az ES6 használatával elkerülheti
this
a helyi változóhoz való hozzárendelést egy nyílfüggvény használatával, amelythis
a környező kód kontextusához kötődik , ahol meg van határozva.
const Cat = function(name, sound) { this.name = name; this.sound = sound; this.makeSound = function() { console.log( this.name + ' says: ' + this.sound ); }; this.annoy = function() { let count = 0, max = 100; const t = setInterval(() => { this.makeSound(); count++; if (count === max) { clearTimeout(t); } }, 500); }; } const kitty = new Cat('Fat Daddy', 'Mrrooowww'); kitty.annoy();