localStorage关键字“getItem”的getter / setter:bug,规范不一致或其他什么?

时间:2013-03-23 22:00:23

标签: javascript local-storage specifications

此代码总结了我的问题:

localStorage.setItem('getItem', 4)
undefined
localStorage.getItem
function getItem() { [native code] }


localStorage['getItem'] = 'user'
"user"
localStorage.getItem
"user"
localStorage.getItem('getItem')
TypeError: Property 'getItem' of object #<Storage> is not a function

使用setItem方法或使用属性访问器更改localStorage的反应方式。

这是一个错误吗?规格不一致?还有别的吗?

我觉得我应该在某个地方举报,但不知道在哪里。

1 个答案:

答案 0 :(得分:5)

  

使用setItem方法或使用属性访问器更改localStorage的反应方式。

     

这是一个错误吗?

看起来不像。来自spec

  

当调用setItem(),removeItem()和clear()方法时   与本地存储区域关联的存储对象x,如果   方法做了什么,然后在每个Document对象中   Window对象的localStorage属性的Storage对象是关联的   除了x之外,存储区域必须相同   解雇了,如下所述。

localStorage对象是IDL attribute,其中包含对Storage接口的引用。 Storage接口扩展了Object.prototype,它引入了额外的属性,并且还定义了自己的属性集。

setItem方法将属性存储在存储列表中。当对象属性发生更改时,该对象还会触发事件,并在这些情况下更新存储区域。

因此setItem的预期行为是将密钥值对存储在存储列表中。 getItem的预期行为是从存储列表中提取与密钥关联的值。

那么当我们尝试直接访问属性时,预期的行为是什么?该行表示键值列表充当“支持的属性”:

  

Storage对象上支持的属性名称是每个名称的键   键/值对当前存在于与该列表关联的列表中   对象

这是什么意思?这意味着those properties are mapped to the getters and setters defined by the interface spec。对于存储,接口规范如下所示:

interface Storage {
  readonly attribute unsigned long length;
  DOMString? key(unsigned long index);
  getter DOMString getItem(DOMString key);
  setter creator void setItem(DOMString key, DOMString value);
  deleter void removeItem(DOMString key);
  void clear();
};

因此localStorage["x"]映射到getItem("x")的值,该值在存储列表中返回“x”的值,localStorage["x"] = y将映射到setItem("x",y)

但是,只有在对象上没有该名称的本机属性时才会运行这些属性,除非在接口上设置了overridebuiltins属性(它不是用于存储)。

  

如果界面上出现[OverrideBuiltins]扩展属性,   它表示对于实现接口的平台对象,   对应于所有对象支持的属性的属性   无论其他什么,名称都会出现在对象上   属性存在于对象或其原​​型链上。这意味着   命名属性将始终隐藏任何属性   否则出现在对象上。这与通常情况形成对比   行为,仅当存在时才会公开命名属性   没有在对象本身或其他地方具有相同名称的属性   它的原型链。

因此,对于属性,我们应该期望如果在对象上定义函数,它将始终在请求上访问/设置该函数。否则,它将检查存储列表并查看它是否有值并更改或返回。

摘要(TL; DR)

规范中的预期行为以及我们在测试时发现的内容是setItemgetItem会将预先存在的属性/函数的值存储为键/值对,并访问它们,不覆盖现有值。当我们尝试直接通过localStorage [“getItem”]访问或修改这些值时,我们将改为命中本地属性,因为默认情况下“支持的属性”规范要求不覆盖内置属性。