zl程序教程

您现在的位置是:首页 >  后端

当前栏目

判断对象是否Window的实现代码

对象代码 实现 判断 是否 window
2023-06-13 09:14:32 时间
直入正题吧.
先看jQuery的$.isWindow函数:

复制代码代码如下:

functionisWin(obj){
returnobj&&typeofobj==="object"&&"setInterval"inobj;
}

这个函数本身是很科学的,它主要是通过检查目标对象是否拥有setInterval属性来判断.
然而问题在于,在缺少约定的情况下,它也许并不太可靠,比如:

复制代码代码如下:

varo={xx:"oo"};
o["setInterval"]=true;
console.log(isWin(o));//true

上例通过给对象字面量添加setInterval属性,欺诈成功.
而事实上,任何一个非null的Object都可以如此伪装,比如数组:

复制代码代码如下:
vararr=[1,2,3];
arr["setInterval"]=true;
console.log(isWin(arr));//true

相比上面的属性属性检查,一个更为妥善的方法是使用对象的toString函数来判断:

复制代码代码如下:
functionisWin(obj){
returnObject.prototype.toString.call(obj)==="[objectWindow]"
}

以上函数在标准浏览器中妥妥的,但同时又带来了新的兼容问题:

复制代码代码如下:
//ie6-8中的结果
Object.prototype.toString.call(window)==="[objectWindow]";//false
Object.prototype.toString.call(window)==="[objectObject]";//true
//chrome
Object.prototype.toString.call(window)==="[objectglobal]";//true
//safari
Object.prototype.toString.call(window)==="[objectDOMWindow]";//true

果然,主要的问题又是来自万恶的ie们.所幸天无绝人之路,这又让我想起了ie中的一个灵异事件:

复制代码代码如下:
//下面两行,信不信?
console.log(window==document);//true
console.log(document==window);//false

写到这里,我想最终的解决方案已经出来了:

复制代码代码如下:
functionisWin(obj){
return/Window|global/.test({}.toString.call(obj))||obj==obj.document&&obj.document!=obj;
}