Den komplette guide til dette i JavaScript

I JavaScript thisoprettes hver funktion automatisk en reference, når du erklærer den.

JavaScript thisligner meget en thisreference i andre klassebaserede sprog som Java eller C # (JavaScript er et prototypebaseret sprog og intet "klasse" -koncept): Det peger på det objekt, der kalder til funktionen (dette objekt kaldes undertiden som kontekst ). I JavaScript imidlertid den thishenvisningen inde funktioner kan bindes til forskellige objekter afhængig af hvor funktionen bliver kaldt .

Her er 5 grundlæggende regler for thisbinding i JavaScript:

Regel 1

Når en funktion kaldes i det globale omfang, er thisreferencen som standard bundet til det globale objekt ( windowi browseren eller globali Node.js). For eksempel:

function foo() { this.a = 2; } foo(); console.log(a); // 2

Bemærk: Hvis du erklærer foo()funktionen ovenfor i streng tilstand, kalder du denne funktion i globalt omfang, thisvil være, undefinedog tildelingen this.a = 2vil give Uncaught TypeErrorundtagelse.

Regel 2

Lad os undersøge eksemplet nedenfor:

function foo() { this.a = 2; } const obj = { foo: foo }; obj.foo(); console.log(obj.a); // 2

Det er klart, at i ovenstående uddrag foo()kaldes funktionen med kontekst er objobjekt, og thisreference er nu bundet til obj. Så når en funktion kaldes med et kontekstobjekt, vil thisreferencen være bundet til dette objekt.

Regel 3

.call, .applyOg .bindalle kan bruges på opkaldet websted til eksplicit binde this. Brug .bind(this)er noget, du kan se i en hel del React-komponenter.

const foo = function() { console.log(this.bar) } foo.call({ bar: 1 }) // 1

Her er et hurtigt eksempel på, hvordan hver enkelt bruges til at binde this:

  • .call(): fn.call(thisObj, fnParam1, fnParam2)
  • .apply(): fn.apply(thisObj, [fnParam1, fnParam2])
  • .bind(): const newFn = fn.bind(thisObj, fnParam1, fnParam2)

Regel 4

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

Den ting, du skal bemærke, er den Point2Dfunktion, der kaldes med newnøgleord, og thisreference er bundet til p1objekt. Så når en funktion kaldes med newnøgleord, opretter den et nyt objekt, og thisreference vil være bundet til dette objekt.

Bemærk: Når du kalder en funktion med newnøgleord, kalder vi den også som konstruktorfunktion .

Regel 5

JavaScript bestemmer værdien af thisved kørsel baseret på den aktuelle kontekst. Så thiskan nogle gange pege på noget andet end hvad du forventer.

Overvej dette eksempel på en Cat-klasse med en metode kaldet makeSound(), der følger mønsteret i regel 4 (ovenfor) med en konstruktorfunktion og newnøgleordet.

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

Lad os nu prøve at give katten en vej til annoy()folk ved at gentage hans lyd 100 gange en gang hvert halve sekund.

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();

Det virker ikke, fordi vi inden i setIntervaltilbagekaldet har oprettet en ny kontekst med globalt omfang, så vi thisikke længere peger på vores kitty-forekomst. I thisstedet for vil en webbrowser pege på Window-objektet, som ikke har en makeSound()metode.

Et par måder at få det til at fungere:

  1. Før du opretter den nye kontekst, skal du tildele thisen lokal variabel med navnet me, eller self, eller hvad du vil kalde det, og bruge den variabel inde i tilbagekaldet.
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();
  1. Med ES6 kan du undgå at tildele thisen lokal variabel ved hjælp af en pilfunktion, der binder thistil konteksten for den omgivende kode, hvor den er defineret.
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();