Connaissez-vous un bon moyen de vérifier si une variable est l'objet de la fenêtre dans JavaScript?
J'ai essayé avec: dans Firefox, il renvoie "[fenêtre d'objet]" code> mais dans IE
"[objet objet]" donc c'est donc Pas la bonne façon. Connaissez-vous un moyen précis de le vérifier? P> p>
9 Réponses :
variable == window Someone could still define a local variable called window. I'm not sure there's a way that's resilient to all such shenanigans. Someone could make an object that copied most of the window properties and functions, including toString.
if(variable.document && variable.location)
Que diriez-vous de:
isWindow = variable === window;
Oui mais j'ai besoin d'un moyen de vérifier chaque fenêtre non seulement de l'actuel.
La vérification de type Strict n'est pas nécessaire lors de la comparaison du même objet.
oui mais j'ai besoin d'un moyen de vérifier chaque fenêtre non seulement de l'actuel em> p>
Il y a quelques façons que vous pouvez faire cela. La méthode la plus simple consiste à rechercher une ou deux propriétés connues sur l'objet de la fenêtre. Il y a aussi la propriété
auto code> - pour chaque fenêtre, vous pouvez vérifier la propriété
auto code> est égale à l'objet de la fenêtre: p>
xxx pré> < / blockquote>
auto code> peut être écrasé et est souvent utilisé comme nom de variable pour conserver le contexte.
@zzzzbov: Alors quoi? La plupart des propriétés peuvent être écrasées, mais vous le voyez rarement que cela se produise lorsque vous essayez de "Conserver le contexte" i> car il ne se produit pas dans la portée globale et que tout développeur de respect de soi déclarerait avec var < / code> ailleurs. Tant que vous vous référez à la fenêtre
code> et pas seulement
auto code>, vous devriez être correct. Si cela compte beaucoup pour quiconque, je suppose qu'ils pouvaient utiliser
window.window code> plutôt que
fenêtre.elf code>, s'ils veulent. Il est protégé d'être écrasé dans la plupart des navigateurs modernes.
@Andye, j'essaie simplement de trouver un moyen plus résilient de vérifier si un objet est une fenêtre code> dans un sens académique. Par exemple,
o = {}; o.self = o; iswindow (o) code> retournerait true dans votre version.
jQuery code> chèques si
seinterval code> est défini, donc
$. ISWindow ({seinterval: 1}) code> retourne de manière incorrecte.
@zzzzbov: Je ne crois pas qu'il y en a un. Les développeurs JQuery ont probablement choisi seinterval code> car il est le moins susceptible d'être réutilisé en tant que nom de propriété sur un autre objet et qu'il est pris en charge par tous les navigateurs connus. Une alternative moderne pourrait être d'utiliser
objet.pototype.tostring (obj) code>, qui retournerait
[objet global] code> ou
[fenêtre d'objet] code> La plupart des navigateurs, avec les principales exceptions étant, c'est-à-dire 7 et moins. Toujours pas complètement résilient, cependant. Peut-être dans 5 ans.
@Andye, j'ai déjà ajouté une réponse à cette question que je pense i> est résiliente. Il a besoin de plus de test pour les cas de bord.
@zzzz: Oups, je n'ai pas réalisé. Je suppose que vous avez compris l'objet objet.pototype.tostring code> sort par vous-même, puis :-)
puisque la fenêtre code> est une variable globale et des variables globales sont des propriétés de l'objet global, Le problème est que cela peut être dupe si nous avons un objet comme celui-ci: p> si ce n'est pas probablement, alors vous pouvez utiliser ce code. P> p> window.window code> sera égal
fenêtre code>. Afin que vous puissiez tester:
Après avoir joué avec de nombreuses options, je pense que c'est la méthode la plus précise de détection si un objet est un navigateur croisé de fenêtre:
(function () { "use strict"; var wStr; wStr = Object.prototype.toString.call(window); function isWindow(arg) { var e, str, self, hasSelf; //Safari returns DOMWindow //Chrome returns global //Firefox, Opera & IE9 return Window str = Object.prototype.toString.call(arg); switch (wStr) { case '[object DOMWindow]': case '[object Window]': case '[object global]': return str === wStr; } ///window objects always have a `self` property; ///however, `arg.self == arg` could be fooled by: ///var o = {}; ///o.self = o; if ('self' in arg) { //`'self' in arg` is true if //the property exists on the object _or_ the prototype //`arg.hasOwnProperty('self')` is true only if //the property exists on the object hasSelf = arg.hasOwnProperty('self'); try { if (hasSelf) { self = arg.self; } delete arg.self; if (hasSelf) { arg.self = self; } } catch (e) { //IE 7&8 throw an error when window.self is deleted return true; } } return false; } }());
J'ai mis à jour votre réponse car il y avait une erreur, puis je l'ai testé et il semble fonctionner, mais je pense que la première partie est trop restrictive car presque chaque navigateur a sa propre façon de convertir la fenêtre en chaîne et peut-être que Il y a plus de 3 variantes.
@ MCK89, je suis principalement préoccupé par les 5: Firefox, Chrome, Safari, Opera et IE. Il serait terriblement agréable que les navigateurs normalisaient d'utiliser '[fenêtre d'objet]' code>, cependant la spécification ECMAScript5 permet à chaque navigateur de choisir sa propre valeur pour la
[[Classe]]] code> Propriété de l'objet global
. Dans ce sens, oui, c'est une implémentation relativement restrictive, mais je pense que c'est beaucoup plus résilient que de vérifier arg.elf == arg code>, qui est facilement dupe.
Je félicite vraiment vos efforts, mais je me demande qui doit être aussi strict. Peut-être qu'une bibliothèque en ferait une utilisation, mais même JQuery pense si (obj && typeof obj === "objet" && "seinterval" dans obj) code> est assez adéquat. Quand est-ce qu'il y a un besoin de quelqu'un d'écrire
o.elf = o code> et quelle est la probabilité que quelqu'un va avoir besoin de vérifier que c'est une fenêtre code> objet code>? Quant à la résilience, votre utilisation de
"Utiliser strict" code> rend la fonction encore moins résilient que
arg.elf === arg code> parce qu'un typeError i> sera Être jeté lorsque vous supprimez une propriété
auto code> avec l'attribut
configurable code> défini sur
false code>.
@Andye, comme je l'ai mentionné dans un commentaire précédent, je suis curieux dans un sens académique. Je me suis mis à écrire un défi d'écrire un (principalement) infaillible iSwindow code> iSwindow. Évidemment remplacer
objet.pototype.tostring code> ou
fonction.pototype.call code> donnerait des résultats incorrects, mais j'aimerais idéalement une fonction pouvant identifier correctement un objet de fenêtre.
@zzzzbov: Eh bien, je peux bien comprendre ça. Hier, quand vous avez commenté ma réponse, j'ai eu un aspect rapide sur le objet.pototype.tostring.tostring.tostring a remarqué que
window.constructor.pototype.tostring! == objet.pototype.tostring code> dans tous les grands navigateurs. J'ai passé les 2 heures suivantes à essayer de comprendre pourquoi et je ne connais toujours pas la réponse. Certaines choses viennent de vous faire comme ça.
@Andye, la plupart des objets natifs ont remplacé Tostring code> dans leurs prototypes; Par exemple, chrome rapporte
fenêtre.constructor code> comme
fonction Domwindow () {...} code>. Qui a un prototype différent de
objet code>. Malheureusement vérifier
arg.tostring () code> est encore moins cohérent que
objet.pototype.tostring.call (arg) code> et plus sujet aux erreurs, car je pouvais facilement voir quelqu'un définissant une personne définissant un Personnalisé
Fenêtre CODE> Objet avec un
TOSTRING code> qui retourne
[fenêtre d'objet] code> ou similaire. Heureusement, j'ai rarement un vrai besoin de vérification de type réelle dans JS.
@zzzzbov: Chrome, Firefox et IE 9+, Domwindow CODE> /
Fenêtre CODE> hérite des propriétés et des méthodes de
objet code> via la chaîne prototype. Inclus dans l'héritage est
Tolocalestring () Code>, qui fait grand chose que
Tostring () code>. J'ai été confus quant à pourquoi
Tostring () code> n'est pas hérité, même si le résultat est le même (sauf en chrome, qui retourne "[objet Domwindow]" i> pour
pour
fenêtre.tostring () code>, plutôt que "[objet global]" i>).
a trouvé cela dans le code source angularjs. Une doublure et une cible sur la cible.
Lorsque la variable est indéfinie, cela lancera une exception (comme la fonction renvoie indéfini au lieu de True / False): l'instanceOf Fenêtre est la meilleure méthode simple pour vérifier. Pour utiliser ce code angularjs, enveloppez-le dans Essayez {} Catch ou avec (type de variable! == 'non défini')
let isWindowObj = (anObject instanceof Window);
code> est une propriété qui pointe à lui-même. Vous pouvez donc utiliser, fenêtre.window == fenêtre code>. Li>
-
Ce code> contient toujours le contexte actuel. Vous pouvez utiliser, ceci == fenêtre code>. Li>
- Dans le cas de plusieurs
Cadre CODE> S présent, chaque image contient son propre objet code> objet code>. Pour vérifier l'objet Global Window CODE>, vous pouvez utiliser la fenêtre WINDOW.PARENT == CODE> LI>
p>
console.log("1 : " + (window.window == window))
console.log("2 : " + (window.window == this))
console.log("3 : " + (window.parent == window))
Pouvez-vous simplement faire un test d'équivalence contre
fenêtre code>?
(quelquevar === fenêtre)? 'Oui': 'Non' Code>
Mais si c'est une fenêtre iframe, cela ne fonctionnera pas.
Je suis curieux, pourquoi avez-vous besoin de faire cela?
IE11 retourne [fenêtre d'objet]