Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/464.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 怪异的IE8内部[[class]]属性行为_Javascript_Dom_Browser_Internet Explorer 8_Local Storage - Fatal编程技术网

Javascript 怪异的IE8内部[[class]]属性行为

Javascript 怪异的IE8内部[[class]]属性行为,javascript,dom,browser,internet-explorer-8,local-storage,Javascript,Dom,Browser,Internet Explorer 8,Local Storage,我最近在IE8上遇到了一些问题(目前我还不知道是9),无法读取和比较一些[[Class]]]属性的值。实际上,它只适用于localStorage对象 我用的是这样的方法 var ToStr = Object.prototype.toString; Object.type = function _type( obj ) { var res = ToStr.call( obj ).split( ' ' )[ 1 ].replace( ']', '' ); if( obj === w

我最近在IE8上遇到了一些问题(目前我还不知道是9),无法读取和比较一些
[[Class]]]
属性的值。实际上,它只适用于
localStorage
对象

我用的是这样的方法

var ToStr = Object.prototype.toString;
Object.type = function _type( obj ) {
    var res = ToStr.call( obj ).split( ' ' )[ 1 ].replace( ']', '' );

    if( obj === window ) {
        res = 'Window';
    }
    else if( res === 'Window' || res === 'Global' ) {
        res = 'Undefined';
    }
    else if( res.indexOf( 'HTML' ) === 0 ) { 
        res = 'Node';
    }

    return ( res );
};
此方法将返回以下值,例如:

var foo = { },
    bar = [ ],
    num = 52,
    win = window;

Object.type( foo ) === 'Object'; // true
Object.type( bar ) === 'Array'; // true
Object.type( num ) === 'Number'; // true
Object.type( win ) === 'Window'; // true
当然,在我所知道的所有浏览器中,只要从对象本身检查
[[Class]]]
属性就可以了。现在,我在
localStorage
对象上调用这个方法

Object.type( win.localStorage ) === 'Storage' // true (not in IE8)
if( obj === window ) { }
IE8只在这里返回
对象
。但是,这并不是真正的问题,当您尝试将
localStorage
对象与
窗口
对象进行比较时,就会出现问题。如您所见,我正在检查传入的参数是否是当前的
窗口
对象

Object.type( win.localStorage ) === 'Storage' // true (not in IE8)
if( obj === window ) { }
如果
obj
now是
window.localStorage
对象,那么这将导致错误

"Class does not support automation"
只有当您尝试将
localStorage
window
进行比较时,才会发生这种情况,您可以将其与任何其他内容进行比较,而不会遇到任何问题。这只是另一个bug还是我可以解决这个问题

我想基本上我的问题是:

在IE8(也可能是IE9)中,您如何知道您正在处理
localStorage
对象?

我最不想做的事情是使用
try-catch
对整个方法进行内部包装,因为它经常被调用

让我完全困惑的是:当你在IE8的控制台中执行
console.log(obj)
时,它会返回你
[object Storage]
(很好!),但是如果你调用
object.prototype.toString.call(obj)
,它会返回
[object object]
。obj的
类型
也是如此,将返回
对象

第二个问题:


IE8
控制台如何打印出正确的
[[Class]]

这一点都不漂亮。获取字符串
“[对象存储]”
的唯一方法是使用以下代码:

obj.constructor.toString();
对于任何本机构造函数,输出和其他浏览器中的预期输出都是本机函数的字符串表示形式。然而,我们在这里讨论的是宿主对象,其中完全应用了不同的规则。有趣的是,尽管IE 9对DOM进行了所有改进,但它给出了相同的结果

这不是一个完全有弹性的解决方案,但这是我能在很短的时间内找到的唯一解决方案,我必须看看这个问题


IE8和IE9的IE8文档模式之间似乎存在差异,
localStorage.constructor
在前者中实际上并不存在。在这种情况下,我认为没有其他可行的解决方案。Duck类型似乎并不有效,因为所有
localStorage
对象的属性名都有点通用。你可以用

window.localStorage === obj

但我不确定IE8在试图覆盖窗口对象的本机属性时的行为(如果它不允许,那么您可能会没事)。

这确实是一个非常奇怪的
IE8
错误!(哦,我爱什么呢

正如
IE8
浏览器评论中所述,我认为只有一种解决方案:

typeof obj === "object" && obj.constructor.toString() === "[object Storage]"
在检查之前,请确保当前浏览器是IE8,否则无法工作,即使在其他版本的IE中也无法工作

顺便说一句,IE与“兄弟姐妹”的兼容性是一个很好的例子

你写道:

只有当您尝试将
localStorage
window
进行比较时,才会发生这种情况,您可以将其与任何其他内容进行比较,而不会遇到任何问题

那你为什么不这样做呢

var ToStr = Object.prototype.toString; 
Object.type = function _type( obj ) { 
    if ( window.localStorage && obj === window.localStorage )
        return 'Storage';
    if ( obj === window ) 
        return 'Window'; 
    var res = ToStr.call( obj ).split( ' ' )[ 1 ].replace( ']', '' ); 
    if ( res === 'Window' || res === 'Global' ) { 
        return 'Undefined'; 
    if ( res.indexOf( 'HTML' ) === 0 ) {  
        return 'Node'; 
    return res; 
}; 
直接回答问题的补充:

  • “…或者我能以某种方式解决这个问题吗?”:你不能。如果浏览器在比较两个特殊值时出现错误,则无法在javascript代码中修复此问题
  • “在IE8(也可能是IE9)中,您如何知道您是否正在处理localStorage对象?”您只需比较
    obj===window.localStorage
    即可检查您是否正在处理它。再简单不过了,不是吗
  • “IE8控制台如何打印出正确的[[Class]]?”内部函数对这些对象的访问方式与javascript非常不同。。。你不能在那里做同样的事情
  • 问候,,
    应使用Steffen

    功能检测(见下文),以避免访问
    本地存储失败

    关于IE8的具体问题,您能否确认该页面正在提供服务,而不是在本地打开?i、 e.URL是
    http://localhost/hello.html
    而不是
    file:///C:/somefolder/hello.html
    IE8不允许对本地打开的文件进行
    localStorage
    ,尽管找不到支持这一点的官方文档(但还有和:),可能值得检查一下,您没有在IE7模式下运行浏览器

    如果您上面的代码应该检测功能可用性,而不是完全检测其他功能,则可以选择使用以下内容:


    我已经找到了一种使用隐式
    toString()
    操作解决IE8行为的方法,ECMAScript规范解释了这种解决方法的意义。隐式的
    toString()
    是:

    "" + window.localStorage
    
    这会隐式地强制调用对象的内部
    toString()
    方法,在IE中,这将返回所需的形式
    [object Storage]
    ,并且您可以让代码在不使用特殊大小写的情况下工作
    window.localStorage

    所以,我一直在寻找一种风险最小的方法来将其合并到您现有的代码中。选择的方法是以与获取类型相同的方式获取类型,并且当且仅当它返回泛型“对象”类型时,然后查看新方法是否有更好的名称可用。所以,过去一切正常的东西都将继续在wa中发挥作用