Javascript检查窗口中是否存在变量

Javascript检查窗口中是否存在变量,javascript,cross-browser,Javascript,Cross Browser,您知道一种检查变量是否是javascript中的窗口对象的好方法吗? 我试过: var variable=window; Object.prototype.toString.call(variable); 在Firefox中返回“[object Window]”,但在IE中返回“[object object]”,所以这不是正确的方法。你知道准确的检查方法吗 variable == window 有人仍然可以定义一个名为window的局部变量。我不确定是否有一种方法可以抵御所有这些恶作剧。有人

您知道一种检查变量是否是javascript中的窗口对象的好方法吗? 我试过:

var variable=window;
Object.prototype.toString.call(variable);
在Firefox中返回
“[object Window]”
,但在IE中返回
“[object object]”
,所以这不是正确的方法。你知道准确的检查方法吗

variable == window
有人仍然可以定义一个名为
window
的局部变量。我不确定是否有一种方法可以抵御所有这些恶作剧。有人可以创建一个复制大多数窗口属性和函数的对象,包括
toString

if(variable == window)
当然,这只会检查变量对象是否是这个窗口(即执行javascript的文档的窗口)

或者,您可以尝试以下方法:

if(variable.document && variable.location)
var q = {};
q.window = q;
并检查是否存在一些窗口字段和/或函数,以便您非常确定它是一个窗口…

只需:

isWindow = variable === window;
三重等于防止了类型强制,否则这将使执行此操作更加困难


是的,但我需要一种方法来检查每个窗口,而不仅仅是当前窗口

有几种方法可以做到这一点。最简单的方法是检查窗口对象上的一个或两个已知属性。还有
self
属性-对于每个窗口,您可以检查
self
属性是否等于窗口对象:

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

由于
window
是一个全局变量,全局变量是全局对象的属性,
window.window
将等于
window
。因此,您可以测试:

if (mysteryVariable.window == mysteryVariable)
    ...
问题是,如果我们有这样一个对象,这可能会被愚弄:

if(variable.document && variable.location)
var q = {};
q.window = q;

如果不太可能,那么您可以使用此代码。

在玩弄了许多选项之后,我相信这是检测对象是否为窗口跨浏览器的最准确方法:

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

我需要执行一些更严格的单元测试,因此请告诉我出现的任何不一致。

在AngularJS源代码中发现了这一点。一艘客轮击中目标

return variable && variable.document && variable.location && variable.alert && variable.setInterval;
  • 窗口
    对象具有指向自身的属性。所以您可以使用,
    window.window==window
  • 始终保存当前上下文。您可以使用,
    this==窗口
  • 如果存在多个
    s,则每个帧都包含自己的
    窗口
    对象。要检查全局
    window
    对象,可以使用
    window.parent==window
  • console.log(“1:”+(window.window==window))
    log(“2:”+(window.window==this))
    
    log(“3:”+(window.parent==window))
    您可以对
    window
    进行等价性测试吗<代码>(somevar==window)?“是”:“否”但如果它是一个iframe窗口,它将不起作用。我很好奇,为什么需要这样做?IE11返回[object window]是的,但我需要一种方法来检查每个窗口,而不仅仅是当前窗口。在比较同一个对象时,不需要进行类型严格检查。
    self
    可以被覆盖,并且经常用作变量名来保留上下文。@zzbov:那么,什么?大多数属性都可以被覆盖,但在尝试“保留上下文”时,您很少会看到这种情况发生,因为它不会发生在全局范围内,任何自尊的开发人员都会在其他任何地方使用
    var
    进行声明。只要您参考的是
    window.self
    ,而不仅仅是
    self
    ,就应该可以了。如果这对任何人都那么重要,我想他们可以使用
    window.window
    而不是
    window.self
    ,如果他们愿意的话。在大多数现代浏览器中,它不会被覆盖。@AndyE,我只是想找到一种更灵活的方法来检查对象是否是学术意义上的
    窗口。例如,
    o={};o、 self=o;isWindow(o)
    将在您的版本中返回true
    jQuery
    检查是否设置了
    setInterval
    ,因此
    $.isWindow({setInterval:1})
    返回错误。@zzzzBov:我认为没有。jQuery开发人员可能选择了
    setInterval
    ,因为它最不可能在另一个对象上被重新用作属性名,并且所有已知的浏览器都支持它。现代的替代方法可能是使用
    Object.prototype.toString(obj)
    ,在大多数浏览器中,它将返回
    [Object global]
    [Object Window]
    ,但IE 7及更低版本除外。但仍然没有完全恢复力。“也许5年后吧!”安德耶,我已经为这个问题补充了一个答案,我认为这个答案很有弹性。边缘情况需要更多的测试。我更新了你的答案,因为有一个错误,然后我测试了它,它似乎可以工作,但我认为第一部分限制太多,因为几乎每个浏览器都有自己的方式将窗口转换为字符串,可能有3个以上的变体。@mck89,我主要关注的是大5:Firefox、Chrome、Safari、Opera和IE。如果浏览器规范化为使用
    “[object Window]”
    ,那就太好了,但是ECMAScript5规范。从这个意义上说,是的,它是一个相对严格的实现,但是我认为它比检查
    arg.self==arg
    更具弹性,这很容易被愚弄。我确实赞扬你的努力,但我想知道谁需要如此严格。也许一个库会利用它,但即使jQuery也认为(obj&&typeof obj===“object”&&setInterval”在obj中)
    足够了。什么时候有人需要编写
    o.self=o
    ,有人需要检查它是否是
    窗口
    对象的可能性有多大?至于弹性,使用
    “use strict”
    会使函数的弹性比
    arg.self===arg
    更低,因为删除
    self
    属性设置为
    Configurable
    false@AndyE的
    属性时会抛出一个类型错误,正如我在