javascript - 为什么不可枚举属性不影响数组内置方法?

标签 javascript arrays object defineproperty

我在玩这个方法 Object.defineProperty()descriptor 参数的 enumerable 属性。在 MDN 上,您可以阅读下一个描述:

enumerable: true if and only if this property shows up during enumeration of the properties on the corresponding object. Defaults to false.

但是,我想知道它不影响遍历可迭代对象的方法的原因,比如 for ... of .在下一个示例中,您可以看到使用 for ... offor ... in 遍历数组之间的比较。

let arr = [1, 2, 3, 4, 5];
Object.defineProperty(arr, "4", {value: 99, enumerable: false});

console.log("For ... of traverse non-enumerable properties:");

for (const ele of arr)
{
    console.log(ele);
}

console.log("For ... in don't traverse non-enumerable properties:");

for (const key in arr)
{
    console.log(arr[key]);
}
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

此外,正如这个问题的标题提到的,built-in 数组方法也会忽略此设置,但是 object 方法不会:

let arr = [1, 2, 3, 4, 5];
Object.defineProperty(arr, "4", {value: 99, enumerable: false});

console.log("forEach(): ");
arr.forEach(x => console.log(x));

console.log("map(): ", arr.map(x => x + 1));

console.log("reduce(): ", arr.reduce((acc, x) => `${acc + x},` , ""));

console.log("Object.keys(): ", Object.keys(arr));

console.log("Object.values(): ", Object.values(arr));
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

我并不是说这是错误的或意外的行为,只是在寻找对这种情况的解释,谢谢!

最佳答案

这是因为 way the array iterator is specified .虽然定义每个键的密集数组是最常见的,但也支持稀疏数组,其中只定义了少数键。为了支持这一点,数组迭代需要能够迭代过去实际不存在的键。例如:

const arr = [];
arr[0] = 0;
arr[10] = 10;

console.log('has 0?', arr.hasOwnProperty(0))
console.log('has 1?', arr.hasOwnProperty(1))

for (let val of arr) {
  console.log(val);
}

基本上,迭代器的定义方式是从一个数字索引移动到下一个数字索引,直到达到数组的长度。在此过程中,它不会检查这些索引是否可枚举,甚至它们是否存在。

For ... of 使用迭代器,因此受此影响,一些数组方法也是如此。 For ... in 不使用迭代器,非数组也不受数组迭代器的影响(尽管它们可能有自己的迭代器)

关于javascript - 为什么不可枚举属性不影响数组内置方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55979227/

相关文章:

javascript - 将两个 Uint32Array 值转换为 Javascript 数字

javascript - 获取当前用户的加星标播放列表或库以及轨道/艺术家

javascript - 在不影响站点的可访问性和 SEO 的情况下使用 JavaScript 的最佳实践和技巧是什么?

arrays - 从排序数组中选择项目<值的有效方法

iOS - 搜索 TableView

javascript - CasperJS 中的 XPath 有什么问题?

java - 如何将数组写入文件Java

python - 如何进入 Python http.client.HTTPResponse 对象?

Java - 给空对象的字段一个值或声明没有构造函数的对象不为空

javascript - 根据值对 javascript 中的对象键进行排序