javascript - 枚举对象属性
问题描述
ecma262规范有一个名为13.7.5.15EnumerateObjectProperties的标题,从它的名字我们可以理解,它负责枚举对象中的属性。这个“半算法”说对象必须遵循以下规则(我不会全部列出,因为其余的都很明显):
- 迭代器的 throw 和 return 方法是 null 并且永远不会被调用。
如果我正确理解了所有内容,那么迭代器应该返回 null,并且在尝试调用这些方法时返回 undefined。尽管这可能意味着迭代器没有这些方法,并且它们实际上是空的,并且不具有 null 类型的空值。
- 枚举期间可以删除目标对象的属性。在迭代器的 next 方法处理之前删除的属性将被忽略。
是的,在枚举过程中确实可以删除该属性(意思是 for...in/of)。
/// Deletion properties on object
var arr = {a:111,b:222,c:333,d:444,e:555,f:666,g:777,h:888,i:999};
for(var item in arr){
if(item == "c") delete arr["c"];
if(item == "e") delete arr["e"];
if(item == "h") delete arr["h"];
console.log(arr[item]); /// when we will be on property "c", we can delete it, it's will accomplished successfull
}
console.log(arr);
但是第二句话让我很困惑。据说在迭代器处理 next 方法之前删除的属性将被忽略。你能证明这样的例子吗?由于某种原因,我陷入了混乱,无法做到。
- 如果在枚举过程中向目标对象添加了新属性,则不保证在活动枚举中处理新添加的属性
这是真的(至少在 chrome 中):
/// Addition properties on object
var arr = {a:111,b:222,c:333,d:444,e:555,f:666,g:777,h:888,i:999};
for(var item in arr){
if(item == "c") arr["c1"] = 1;
if(item == "e") arr["e1"] = 1;
if(item == "h") arr["h1"] = 1;
console.log(arr[item]);
}
console.log(arr);
- EnumerateObjectProperties 必须通过调用其 [[OwnPropertyKeys]] 内部方法来获取目标对象自己的属性键。
在我看来,这是本段中的重要陈述之一。如您所知, [[OwnPropertyKeys]] 定义了属性在对象中列出的顺序。因此,我们看一下标题的第二段:
枚举属性的机制和顺序没有指定,但必须符合下面指定的规则。
嗯?什么?你能解释一下什么鬼吗?
解决方案
据说在迭代器处理 next 方法之前删除的属性将被忽略。
这意味着您可以在迭代期间删除尚未到达的元素,然后将不会枚举它们:
const obj = { a: 1, b: 2, c: 3 };
for(let prop in obj) {
console.log('prop', prop);
delete obj.b;
}
这实际上与您可以使用for of
循环和执行的任何操作不同Object.entries()
:
const obj = { a: 1, b: 2, c: 3 };
for(let [prop] of Object.entries(obj)) {
console.log('prop', prop);
delete obj.b;
}
枚举属性的机制和顺序没有指定,但必须符合下面指定的规则。
引擎在这里有一些自由。有一些规则要遵循,但例如,引擎选择枚举原型链的顺序似乎是开放的。它必须调用[[OwnPropertyKeys]]
并不意味着它不允许在处理之前诉诸结果。
推荐阅读
- python-3.x - 从彩色图像中删除网格
- oracle - 如何将此 Oracle 存储过程中的 SQL 转换为动态 SQL?
- java - 如何让 gradle 从“src”目录而不是“bin/test”中读取
- node.js - hyperledger composer/fabric 中的主数据和交易数据关系
- pseudocode - 查看地址是否已写在句子中的算法
- uwp - 为 Packager 项目创建 appx Bundle 文件时,未为项目设置 OutputPath 属性
- html - 如何在css中设计这个重叠
- python - 天蓝色笔记本中的 Jupyter 服务器扩展 url 模式
- javascript - CSS 列数 - 水平对齐 - 砌体网格
- angular - 如何实现组件之间的拖放