Javascript检查窗口中是否存在变量
您知道一种检查变量是否是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的局部变量。我不确定是否有一种方法可以抵御所有这些恶作剧。有人
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)
将在您的版本中返回truejQuery
检查是否设置了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的属性时会抛出一个类型错误,正如我在