2010-06-23 16 views
10

¿conoces una buena manera de comprobar si una variable es el objeto ventana en javascript? he intentado con:Javascript comprobar si una variable es la ventana

var variable=window; 
Object.prototype.toString.call(variable); 

En Firefox vuelve "[object Window]" pero en IE "[object Object]" de manera que no es la manera correcta. ¿Conoces una forma precisa de verificarlo?

+0

¿Puede usted acaba de hacer una prueba de equivalencia con respecto 'window'? '(somevar === ventana)? 'sí': 'no'' –

+0

Pero si se trata de una ventana iframe no funcionará. – mck89

+0

Tengo curiosidad, ¿por qué necesitas hacer esto? –

Respuesta

10

Sí, pero necesito una manera de comprobar todas las ventanas no sólo el actual

Hay algunas maneras que usted puede hacer esto. El método más simple es verificar para una o dos propiedades conocidas en el objeto de la ventana. También existe la propiedad self - para cada ventana, podrías comprobar la propiedad self es igual al objeto de ventana:

myvar.self == myvar; 
window.self == window; 
frameElement.contentWindow.self == frameElement.contentWindow; 
+0

¡Perfecto gracias! – mck89

+1

'self' se puede sobrescribir y se usa a menudo como nombre de variable para conservar el contexto. – zzzzBov

+0

@zzzzBov: Entonces, ¿qué? La mayoría de las propiedades se pueden sobrescribir, pero rara vez se verá esto cuando se trate de * "mantener el contexto" * porque no ocurre en el ámbito global y cualquier desarrollador que se precie declare con 'var' en cualquier otro lugar. Siempre que te refieras a 'window.self' y no a' self', deberías estar bien. Si a alguien le importa tanto, supongo que podrían usar 'window.window' en lugar de' window.self', si así lo desean. Está protegido de ser sobrescrito en la mayoría de los navegadores modernos. –

1
variable == window 

Alguien se podría definir una variable local llamada window. No estoy seguro de que haya una manera de ser resiliente a todos esos chanchullos. Alguien podría crear un objeto que copiara la mayoría de las propiedades y funciones de la ventana, incluido toString.

1
if(variable == window) 

Por supuesto, solo se comprueba si el objeto variable es esta ventana (es decir, la ventana del documento que ejecuta el javascript).

Alternativamente, usted podría intentar algo como esto:

if(variable.document && variable.location) 

Y comprobar la existencia de unos campos y/o funciones de la ventana por lo que son bastante seguro que se trata de una ventana ...

2

¿Qué tal:

isWindow = variable === window; 

El triple es igual a la coacción impide escribir que de otro modo hacer esto mucho más difícil de hacer.

+2

Sí, pero necesito una forma de verificar cada ventana, no solo la ventana actual. – mck89

+0

La verificación estricta de tipo no es necesaria cuando se compara el mismo objeto. –

0

Desde window es una variable global y las variables globales son propiedades del objeto global, window.window será igual window . Por lo que podría probar:

if (mysteryVariable.window == mysteryVariable) 
    ... 

El problema es que esto puede ser engañado si tenemos un objeto como éste:

var q = {}; 
q.window = q; 

Si eso no es probable, entonces usted puede utilizar este código.

2

Después jugando un poco con muchas opciones, creo que este es el método más preciso para detectar si un objeto es una ventana a través del navegador:

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

que tendrá que realizar algunas pruebas unitarias más riguroso, entonces por favor avíseme sobre cualquier incoherencia que surja.

+0

He actualizado tu respuesta porque hubo un error, luego la he probado y parece funcionar, pero creo que la primera parte es demasiado restrictiva porque casi todos los navegadores tienen su propia forma de convertir la ventana en cadena y quizás haya más de 3 variantes. – mck89

+0

@ mck89, me preocupan principalmente los 5 grandes: Firefox, Chrome, Safari, Opera e IE. Sería terriblemente agradable si los navegadores se normalizaran para usar ''[object Window]'', sin embargo, la especificación ECMAScript5 [permite a cada navegador elegir su propio valor para la propiedad '[[Class]]' del objeto global] (http: //es5.github.com/#x15.1). En ese sentido, sí, es una implementación relativamente restrictiva, sin embargo, creo que es mucho más resistente que comprobar 'arg.self == arg', que es fácilmente engañado. – zzzzBov

+0

Realmente recomiendo su esfuerzo, pero me pregunto quién necesita ser tan estricto. Tal vez una biblioteca haría uso de él, pero incluso jQuery piensa 'if (obj && typeof obj ===" object "&&" setInterval "en obj)' es lo suficientemente adecuado. ¿Cuándo hay alguna vez la necesidad de que alguien escriba 'o.self = o', y qué tan probable es que alguien tenga que comprobar que se trata de un objeto' window'? En cuanto a la resistencia, el uso de '" use strict "' hace que la función sea aún menos resistente que 'arg.self === arg' porque se generará * TypeError * cuando elimine una propiedad' self' con 'Configurable' atributo establecido en 'falso'. –

4

Encontré esto en el código fuente de AngularJS. Un trazador de líneas y un golpe en blanco.

return variable && variable.document && variable.location && variable.alert && variable.setInterval; 
+0

Cuando la variable no está definida, arrojará una excepción (ya que la función devuelve indefinido en lugar de verdadero/falso): instancia de la ventana es el mejor método simple para verificar. Para utilizar este código AngularJS, envuélvelo en try {} catch o con (typeof variable! == 'undefined') –

0
var x = new Window(); 
x instanceof Window 
var y = [] 
y instanceof Window 
+2

Poco sabe el usuario, pero hemos abierto una ventana sin que ellos lo sepan ... – redolent

0
let isWindowObj = (anObject instanceof Window); 
Cuestiones relacionadas