javascript - 在不是数组的可迭代对象上调用 Array.map 是否有效?
问题描述
这篇文章:使用 filter()、map() 和箭头函数遍历 DOM提倡这样的使用,Array.map
这在我看来很奇怪。更具体地说,文章的作者声称以下代码是有效的,并且实际上比替代代码更好Array.from(elements).map(...)
:
var elements = document.getElementsByClassName("bgflag");
BgFlags = Array.prototype.map.call(elements,
element =>
({
height: element.offsetTop,
bgsrc: element.dataset.bgsrc,
bgcolor: element.dataset.bgcolor,
size: element.dataset.size,
name: element.id,
image: parseInt(element.dataset.image)
})
);
这对我未经训练的眼睛来说似乎是最可疑的。我们正在呼吁Array.prototype.map
一些不是Array
. 除非在某处明确声明这是允许的,否则这对我来说就像是未定义的行为。我快速浏览了相关的 MDN 文档,但找不到那里允许这样的用法。
然而,文章的作者强调:
即使 map() 是 Array.prototype 的一个函数,它也适用于任何类似数组的可迭代对象。
正如他所声称的那样,这种使用是否有效?如果是这样,其他Array.prototype.*
功能是否也是如此,例如filter
, slice
, 甚至pop
, push
, 其他?
解决方案
除非在某处明确说明这是允许的
是的,它在规范中:
该
map
功能是故意通用的;它不要求它的 this 值是一个Array
对象。因此,它可以转移到其他类型的对象中用作方法。
大多数方法Array.prototype
都有这个注释。不能这样使用的没有那个注释。
因此,您是否要使用它纯粹是风格问题。不同的人会对风格的好/坏/冷漠有不同的看法。
旁注:如果你打算使用map
这种方式,而不是每次都写那个手写体,给自己一个捷径:
const map = Function.prototype.call.bind(Array.prototype.map);
然后像这样使用它:
const result = map(arrayLike, e => /*...*/);
现场示例:
const map = Function.prototype.call.bind(Array.prototype.map);
const arrayLike = {
0: "zero",
1: "one",
2: "two",
length: 3
};
const result = map(arrayLike, e => e.toUpperCase());
console.log(result);
推荐阅读
- perl - 有没有办法确定哪些 perl 特定选项被传递给脚本?
- npm - 如何将节点模块导入到苗条组件中
- android - 为什么jetpack compose海拔会夹住我的影子?
- python - PermissionError: [WinError 32] 适合文件
- c# - 如何使用 C# open-xml SDK 以 json 格式从 Word 文档中获取文本?
- javascript - 如果使用 highcharts 中的刻度位置,如何按降序对 yaxis 进行排序?
- angular - 在哪里订阅 Angular 中的 observable、构造函数或 ngoninit
- dockerfile - Dockerfile:在构建期间添加和删除文件:RUN rm -r 的问题
- typescript - Typescript - 根据 keyof 给出的属性确定子类型
- c# - 行进立方体未创建预期的网格