Typ reference

Podrobná jazyková funkce

Tento článek se zabývá pokročilým tématem, abyste lépe porozuměli určitým okrajovým případům.

To není důležité. Mnoho zkušených vývojářů žije dobře, aniž by to věděli. Čtěte dál, pokud chcete vědět, jak to funguje pod kapotou.

Dynamicky vyhodnocované volání metody může ztratit this .

Například:

let user = {
 name: "John",
 hi() { alert(this.name); },
 bye() { alert("Bye"); }
};

user.hi(); // works

// now let's call user.hi or user.bye depending on the name
(user.name == "John" ? user.hi : user.bye)(); // Error!

Na posledním řádku je podmíněný operátor, který volí buď user.hi nebo user.bye . V tomto případě je výsledek user.hi .

Poté je metoda okamžitě volána se závorkami () . Ale to nefunguje správně!

Jak vidíte, volání má za následek chybu, protože hodnota "this" uvnitř hovoru se změní na undefined .

Funguje to (metoda bodových objektů):

user.hi();

To ne (vyhodnocená metoda):

(user.name == "John" ? user.hi : user.bye)(); // Error!

Proč? Pokud chceme pochopit, proč se to děje, pojďme se podívat pod pokličku toho, jak obj.method() volání funguje.

Vysvětlení typu reference

Při bližším pohledu si můžeme všimnout dvou operací v obj.method() prohlášení:

  1. Nejprve tečka '.' načte vlastnost obj.method .
  2. Poté v závorce () provést.

Jak tedy vypadá informace o this přejít z první části do druhé?

Pokud tyto operace uvedeme na samostatné řádky, pak this se určitě ztratí:

let user = {
 name: "John",
 hi() { alert(this.name); }
};

// split getting and calling the method in two lines
let hi = user.hi;
hi(); // Error, because this is undefined

Zde hi = user.hi vloží funkci do proměnné a na posledním řádku je zcela samostatná, takže neexistuje žádný this .

Vytvořit user.hi() volání fungují, JavaScript používá trik – tečku '.' nevrací funkci, ale hodnotu speciálního typu reference.

Referenční typ je „typ specifikace“. Nemůžeme to explicitně použít, ale používá se interně jazykem.

Hodnota typu reference je kombinací tří hodnot (base, name, strict) , kde:

  • base je objekt.
  • name je název vlastnosti.
  • strict má hodnotu true, pokud use strict je v platnosti.

Výsledek přístupu k vlastnosti user.hi není funkce, ale hodnota typu reference. Pro user.hi v přísném režimu je to:

// Reference Type value
(user, "hi", true)

Při závorkách () jsou volány na referenčním typu, obdrží úplné informace o objektu a jeho metodě a mohou nastavit správnou hodnotu this (=user v tomto případě).

Typ reference je speciální interní typ „zprostředkovatele“, jehož účelem je předávat informace z tečky . na volání závorek () .

Jakákoli jiná operace, jako je přiřazení hi = user.hi zahodí typ odkazu jako celek, nabere hodnotu user.hi (funkce) a předá ji dál. Takže jakákoli další operace „ztratí“ this .

Výsledkem je tedy hodnota this je předán správným způsobem pouze v případě, že je funkce volána přímo pomocí tečky obj.method() nebo hranaté závorky obj['method']() syntaxe (zde dělají totéž). Tento problém lze vyřešit různými způsoby, například func.bind().

Shrnutí

Reference Type je interní typ jazyka.

Čtení vlastnosti, například s tečkou . v obj.method() nevrací přesně hodnotu vlastnosti, ale speciální hodnotu „referenčního typu“, která ukládá jak hodnotu vlastnosti, tak objekt, ze kterého byla převzata.

To je pro následné volání metody () získat objekt a nastavit this k tomu.

Pro všechny ostatní operace se typ reference automaticky stává hodnotou vlastnosti (v našem případě funkcí).

Celá mechanika je našim očím skryta. Záleží pouze na jemných případech, jako když je metoda získávána dynamicky z objektu pomocí výrazu.