【问题标题】:Is it valid to call Array.map on an iterable that is not an array?在不是数组的可迭代对象上调用 Array.map 是否有效?
【发布时间】:2018-11-15 06:38:06
【问题描述】:

这篇文章:Traversing the DOM with filter(), map(), and arrow functions 提倡使用 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。除非在某处明确声明这是允许的,否则这对我来说就像是未定义的行为。我快速浏览了the relevant MDN documentation,但找不到那里允许这样的用法。

然而,文章的作者强调:

尽管 map() 是 Array.prototype 的函数,但它适用于任何类似数组的可迭代对象。

像他声称的那样,这样的使用是否有效?如果是这样,其他Array.prototype.* 函数是否也是如此,例如filterslice,甚至可能是poppush 等?

【问题讨论】:

  • 是的,这是一种非常普遍的做法。
  • 来自 ES 5.1 规范:map 函数是有意通用的;它不要求它的 this 值是一个 Array 对象。因此,它可以转移到其他类型的对象中用作方法。映射函数能否成功应用于宿主对象取决于实现。

标签: javascript arrays javascript-objects array.prototype.map


【解决方案1】:

除非某处明确说明这是允许的

是的,在the specification:

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);

【讨论】:

    【解决方案2】:

    是的,通常有效。不过我同意你:

    Array.from(elements).map(element => /*..*/);
    // Or even
    Array.from(elements, element => /*...*/);
    

    干净多了。

    【讨论】:

      猜你喜欢
      • 2016-04-09
      • 1970-01-01
      • 2020-10-23
      • 1970-01-01
      • 2020-04-02
      • 2011-10-05
      • 2018-03-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多