为啥这些属性不可枚举?
Posted
技术标签:
【中文标题】为啥这些属性不可枚举?【英文标题】:Why are these properties not enumerable?为什么这些属性不可枚举? 【发布时间】:2017-12-05 23:03:30 【问题描述】:我有一个简单的对象对象:
window.abilities =
migrate:
name:"Migrate",
description:"Move your tribe to another area; generate all new resources. Takes one time unit.",
image:"migrate.png",
action:"Migrate",
unlocked:true
,
eradicate:
name:"Eradicate species",
description:"Remove a troublesome plant or animal",
image:"migrate.png",
action:"Eradicate",
unlocked:false
我正在使用 for ... in ... 循环来迭代这个对象并生成 UI 元素:
for(ability in window.abilities)
if(ability.unlocked)
$("#abilities").append(genAbilityCard(ability.name,ability.image,ability.description,ability.action));
但是,每个能力变量都是空的——它只有键,没有属性(名称、描述等)。这些属性似乎是不可枚举的——尽管以这种方式创建的属性在默认情况下应该是可枚举的!
如何在不使用 Object.defineProperty 或类似的笨方法的情况下使这些属性可隐式枚举?
【问题讨论】:
How do I loop through or enumerate a javascript object? 的可能重复项。这是一个古老且得到很好回答的问题,循环只会为您提供密钥。 【参考方案1】:如果您能够使用 ES6 和 for... of
循环,Alberto 的答案是您最好的选择,也是最干净的选择。
如果你受限于 ES5,你也可以使用for ... in
。如您所见,for ... in
仅枚举键(属性名称),而不是属性值,但是一旦您知道属性名称,就很容易获取属性值:
var abilityName, ability;
for(abilityName in window.abilities)
ability = window.abilities[abilityName];
if(ability.unlocked)
$("#abilities").append(genAbilityCard(ability.name,ability.image,ability.description,ability.action));
您获得属性名称的事实意味着您正在成功枚举属性。 Javascript 在 for ... in
的工作方式上有点奇怪。
【讨论】:
我不知道什么会限制我使用 ES5; Alberto 的代码有效,但感谢您提供更详细的信息! @SPavel 这真的取决于你的目标平台/目标浏览器。例如,IE11 不支持 ES6 的大多数功能,包括for... of
。有关在哪些环境中支持的更多详细信息,您可以查看kangax.github.io/compat-table/es6。【参考方案2】:
尝试使用 for..of
和 Object.values
进行迭代(仅限 ES6):
for (const ability of Object.values(window.abilities))
if (ability.unlocked)
$("#abilities").append(genAbilityCard(ability.name,ability.image,ability.description,ability.action));
【讨论】:
工作得很好,谢谢!我无法在据称现有的工作答案中得到任何东西,但这解决了它。 很高兴为您提供帮助!关于该解决方案的唯一警告是它仅限于 >= ES6。如果你需要在以上是关于为啥这些属性不可枚举?的主要内容,如果未能解决你的问题,请参考以下文章
可枚举属性和不可枚举属性(for...in循环和Objec.keys()和Object.getOwnPropertyNames())