转换javascript"几乎是数组"最简洁的方法是什么?进入"阵列"?

时间:2016-08-13 17:21:22

标签: javascript arrays

在过去的几个月里,我一直在使用JavaScript,并且发现它在多年未使用它之后真的令人耳目一新。

那就是说,特别是让我烦恼的一件事就是它的'它如何描述的不一致" []"构造

特别是,我习惯让阵列有一个" map"功能,但很多东西都是" []" -enclosed不支持地图,但通常支持同义词,有时根本不支持。

示例:

  1. 的document.getElementById('我的-DIV&#39)。儿童
  2. 根本没有可映射性,每次我需要映射它时,我不得不求助于循环。

    1. document.querySelectorAll('#my-div *')
    2. forEach :: callback -> undefined

      与map不同,不会返回数组,因此链接转换是"奇怪的"因为除了映射对象之外,还必须将结果存储在数组中以继续。

      这意味着以下工作无效。

      (() => {
          document.querySelectorAll('#my-div *').forEach((divObject) => {
              console.log('found a ' + divObject.tagName + '.');
              return divObject;
          }).forEach((divObject) => {
              console.log('more transformations on ' + divObject.tagName + '.');
              return divObject;
          });
      })();
      

      但这会:

      (() => {
          var children = [];
      
          document.querySelectorAll('#my-div *').forEach((divObject) => {
              children.push(divObject);
          });
      
          children.map((divObject) => {
              console.log('found a ' + divObject.tagName + '.');
              return divObject;
          }).map((divObject) => {
              console.log('more transformations on ' + divObject.tagName + '.');
              return divObject;
          });
      })();
      

      但复制元素"逐个"在forEach中,只是额外的工作,没有任何实际用途,通常应该在发布这样的代码之前进行优化,因为它没有充分的理由对性能造成损害。

      1. jQuery的地图正常运行。例如$('#my-div *')有一个map :: callback -> array that supports map operation。所以它可以按预期链接。
      2. 问题

        是否有一种更清晰的方法来克服类似数组的接口(看起来像#34; Arrays"但不支持Array.prototype.map)的不一致性,而不是必须使用第一次迭代一个for循环,推送内容,只有在知道它的行为与你认为的行为相同之后?

3 个答案:

答案 0 :(得分:1)

对于所有奇异的数组,如节点列表等,如果它们是可迭代的,你可以安全地做到像

var properArray = [...arrayLike]var properArray = Array.from(arrayish)

或者你甚至可以这样做

var properarray = Array(arrayish.length),
              i = 0;
for (var key of arrayish) while i < arrayish.length properArray[i++] = arrayish(key);

如果您有像

这样的对象

&#13;
&#13;
var o = {prop_1:"one thing",
         prop_2:"another thing"},
    a = [];

o[Symbol.iterator] = function* (){
                       var oks = Object.keys(this);
                       for (var key of oks) yield this[key]
                     }
a = [...o];
console.log(a);
&#13;
&#13;
&#13;

你可以使它可迭代并以相同的方式将其转换为数组;

答案 1 :(得分:1)

您可以使用.apply

来避免复制数组
var nodeList = document.getElementsByTagName("p");

Array.prototype.map.apply(nodeList, function(node) {
  // do something with node
});

(显然,对.map()的调用本身会创建一个新阵列,但无论如何都会发生。)

答案 2 :(得分:0)

我的建议是:避免链接

转换为数组并映射只是为了能够链forEach是一种浪费。

相反,只需将NodeList存储在变量中。

&#13;
&#13;
var nodes = document.querySelectorAll('*');
nodes.forEach(node =>
  console.log('found a ' + node.tagName + '.'))
nodes.forEach(node =>
  console.log('more transformations on ' + node.tagName + '.'));
&#13;
&#13;
&#13;

注意NodeList在DOM4之前是不可迭代的。