javascript - Function.prototype.call mení typeof this mimo strict módu; prečo?


var example = function () {
  console.log(typeof this);
  return this;
};

V prísnom režime: example.call('test') # vypíše 'string'

Inak, example.call('test') # vypíše 'object'

Avšak, console.log(example.call('test')) vypíše test (ako by ste očakávali)

Prečo Function.call mení typeof 'test' === 'string' viazané na this vo vnútri example?

Odpoveď č. 1

Pri použití call() a nastavení argumentu this na primitívnu hodnotu sa táto primitívna hodnota vždy premení na objekt, takže dostanete objekt reťazca namiesto primitívneho reťazca

String {0: "t", 1: "e", 2: "s", 3: "t", length: 4, ...

Dokumentácia pre call() na MDN uvádza, že

thisArg
Hodnota this poskytnutá pre volanie funkcie.
Poznámka: toto nemusí byť skutočná hodnota, ktorú metóda vidí: ak je metóda funkciou v kóde, ktorý nie je v prísnom režime, null a undefined budú nahradené globálnym objektom, a primitívne hodnoty budú prevedené na objekty.

Takže v nesprísnenom režime je primitívna hodnota reťazca prevedená na objekt, čo je tiež špecifikované v štandarde ECMA, Príloha C

obmedzenia prísneho režimu a výnimky
Ak sa this vyhodnocuje v kóde prísneho režimu, potom sa hodnota this neprevádza na objekt.
Hodnota this null alebo undefined sa neprevádza na globálny objekt a primitívne hodnoty sa neprevádzajú na obalové objekty.
Hodnota this odovzdaná cez volanie funkcie (vrátane volaní vykonaných pomocou Function.prototype.apply a Function.prototype.call) neprevádza odovzdanú hodnotu this na objekt