Quelqu'un peut-il expliquer cette méthode Javascript?
-
20-09-2019 - |
Question
Source d'origine: http://twitter.com/tobeytailor/status/8998006366
(x=[].reverse)() === window // true
Je l'ai remarqué que ce comportement affecte tous les types natifs. Ce qui se passe ici exactement?
La solution
est de faire avec les travaux de liaison this
de façon bizarre en JavaScript.
[].reverse
est la méthode reverse
sur une liste vide. Si vous l'appelez, par l'un des:
[].reverse();
[]['reverse']();
([].reverse)();
il exécute avec this
lié à l'instance de liste []
. Mais si vous le détachez:
x= [].reverse;
x();
il exécute sans this
contraignant, de sorte this
dans les points de fonction à l'objet global (window
), dans l'une des pires, des erreurs de conception les plus trompeuses JavaScript.
(x=[].reverse)()
fait aussi le détachement. L'opérateur d'affectation retourne le même objet de fonction, il a été passé si on dirait que ça ne fait rien, mais il a l'effet secondaire de briser le cas particulier limitée que JavaScript provoque pour lier this
.
Vous dites:
Array.prototype.reverse.call(window)
reverse
, comme beaucoup d'autres méthodes de Array.prototype
, est définie par ECMAScript pour travailler sur un objet de séquence comme native. Il renverse les éléments clés avec numéro chaîne (jusqu'à object.length
) et renvoie l'objet. Donc, il va renvoyer l'objet qui a été passé pour tout type qui possède une propriété length
.
window
a une propriété de longueur, ce qui correspond à window.frames.length
, afin d'appeler cette méthode avec this
pointant window
fonctionnera et retourner le window
. En théorie, il peut encore échouer, parce que:
-
window
est autorisé à être un « objet hôte » plutôt qu'un « objet natif »; dans ce cas, les garanties sur ce que vous pouvez passer aux méthodes d'autres prototypes ne sont pas forcément; et - si la fenêtre a images / iframes, il essaierait effectivement d'inverser leur ordre, qui ne fonctionnerait pas parce que la collection d'images est en lecture seule.
Cependant, dans les navigateurs actuels le premier cas, fonctionne et ce dernier échoue silencieusement sans erreur, vous obtenez toujours le comportement de ===window
et non une exception.