12
votes

Vérifier JavaScript si une variable est la fenêtre

Connaissez-vous un bon moyen de vérifier si une variable est l'objet de la fenêtre dans JavaScript? J'ai essayé avec: xxx

dans Firefox, il renvoie "[fenêtre d'objet]" mais dans IE "[objet objet]" donc c'est donc Pas la bonne façon. Connaissez-vous un moyen précis de le vérifier?


4 commentaires

Pouvez-vous simplement faire un test d'équivalence contre fenêtre ? (quelquevar === fenêtre)? 'Oui': 'Non'


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]


9 Réponses :


0
votes
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.

0 commentaires

0
votes
if(variable.document && variable.location)

0 commentaires

1
votes

Que diriez-vous de:

isWindow = variable === window;


2 commentaires

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.



12
votes

oui mais j'ai besoin d'un moyen de vérifier chaque fenêtre non seulement de l'actuel

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 - pour chaque fenêtre, vous pouvez vérifier la propriété auto est égale à l'objet de la fenêtre: xxx < / blockquote>


6 commentaires

auto 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" 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 et pas seulement auto , vous devriez être correct. Si cela compte beaucoup pour quiconque, je suppose qu'ils pouvaient utiliser window.window plutôt que fenêtre.elf , 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 dans un sens académique. Par exemple, o = {}; o.self = o; iswindow (o) retournerait true dans votre version. jQuery chèques si seinterval est défini, donc $. ISWindow ({seinterval: 1}) retourne de manière incorrecte.


@zzzzbov: Je ne crois pas qu'il y en a un. Les développeurs JQuery ont probablement choisi seinterval 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) , qui retournerait [objet global] ou [fenêtre d'objet] 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 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 sort par vous-même, puis :-)



-1
votes

puisque la fenêtre est une variable globale et des variables globales sont des propriétés de l'objet global, window.window sera égal fenêtre . Afin que vous puissiez tester: xxx

Le problème est que cela peut être dupe si nous avons un objet comme celui-ci: xxx

si ce n'est pas probablement, alors vous pouvez utiliser ce code.


0 commentaires

1
votes

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


7 commentaires

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]' , cependant la spécification ECMAScript5 permet à chaque navigateur de choisir sa propre valeur pour la [[Classe]]] 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 , 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) est assez adéquat. Quand est-ce qu'il y a un besoin de quelqu'un d'écrire o.elf = o et quelle est la probabilité que quelqu'un va avoir besoin de vérifier que c'est une fenêtre objet ? Quant à la résilience, votre utilisation de "Utiliser strict" rend la fonction encore moins résilient que arg.elf === arg parce qu'un typeError sera Être jeté lorsque vous supprimez une propriété auto avec l'attribut configurable défini sur false .


@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 iSwindow. Évidemment remplacer objet.pototype.tostring ou fonction.pototype.call 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 window.constructor.pototype.tostring! == objet.pototype.tostring 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 dans leurs prototypes; Par exemple, chrome rapporte fenêtre.constructor comme fonction Domwindow () {...} . Qui a un prototype différent de objet . Malheureusement vérifier arg.tostring () est encore moins cohérent que objet.pototype.tostring.call (arg) et plus sujet aux erreurs, car je pouvais facilement voir quelqu'un définissant une personne définissant un Personnalisé Fenêtre Objet avec un TOSTRING qui retourne [fenêtre d'objet] 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 / Fenêtre hérite des propriétés et des méthodes de objet via la chaîne prototype. Inclus dans l'héritage est Tolocalestring () , qui fait grand chose que Tostring () . J'ai été confus quant à pourquoi Tostring () n'est pas hérité, même si le résultat est le même (sauf en chrome, qui retourne "[objet Domwindow]" pour pour fenêtre.tostring () , plutôt que "[objet global]" ).



5
votes

a trouvé cela dans le code source angularjs. Une doublure et une cible sur la cible. xxx


1 commentaires

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')



-1
votes
let isWindowObj = (anObject instanceof Window);

0 commentaires

0
votes
  1. La fenêtre code> est une propriété qui pointe à lui-même. Vous pouvez donc utiliser, fenêtre.window == fenêtre code>. Li>
  2. Ce code> contient toujours le contexte actuel. Vous pouvez utiliser, ceci == fenêtre code>. Li>
  3. 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))

0 commentaires