为啥这些属性不可枚举?

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..ofObject.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())

javascript defineProperty 使属性不可枚举

是否可以获得对象的不可枚举的继承属性名称?

对象枚举属性