【问题标题】:made my own forEach function in javascript, but it's returning undefined在javascript中创建了我自己的forEach函数,但它返回未定义
【发布时间】:2017-04-05 13:25:25
【问题描述】:

作为我正在学习的 Javascript 课程的一部分,您应该创建自己的 forEach 函数,该函数接受两个参数,一个数组和一个回调。它应该将每个元素、它的索引和数组本身传递给回调。应该返回未定义。这是我的:

function myForEach (arr, cb) {
  for(var i = 0; i < arr.length; i++) {
    var elem = arr[i];

    cb(elem, i, arr);
  }
}

然后,您应该在另一个函数中引用它并使用它来执行一些示例函数。特别是,您应该编写一个接受数组和回调作为参数的函数,并且它应该将回调传递给每个元素、其对应的索引和数组本身。然后它应该返回一个新数组,其中新数组中的每个元素都是回调的返回值。这是有问题的功能:

function myMap(arr, cb) {
  var mapped = [];

  mapped.push(myForEach(arr, cb));

  return mapped;
}

我不明白为什么(在这个例子中),当传递的回调应该返回一个值时,我的值是未定义的:

console.log(myMap([1, 2, 3], function(ele, i, arr){
  return ele * i;
}));
// [0, 2, 6] expected return value

在平衡返回未定义与未定义的内容以及如何将回调中的值实际推送到我的空数组中时,这里通常有点困惑。

【问题讨论】:

  • 你的 forEach 不返回任何东西,所以这和return undefined一样
  • 问题出在这行 mapped.push(myForEach(arr, cb)); myForEach 不会返回进入回调的每个项目(实际上它什么也不返回,这就是您未定义的原因)。以下是如何使其工作,手动调用 cb 然后将其推送到映射数组。像这样:jsfiddle.net/2htuer9m
  • "它应该将回调传递给每个元素" - 我不这么认为 :-)
  • @HattanShobokshi 啊,是的 - 我和一位同事讨论了这个问题,他还指出你必须运行一个函数作为 myForEach 的 cb ,它将值推送到你的空数组,以及你的值're push 只是传递给 myMap 的 cb 的值。
  • 点赞function myMap(arr, cb) { var mapped = []; myForEach(arr, function(ele, i, arr) { mapped.push(cb(ele, i, arr)); }); return mapped; }

标签: javascript arrays foreach


【解决方案1】:

这是你的问题。

console.log(myMap([1, 2, 3], function(ele, i, arr){
  return ele * i;
}));

在第二个参数中,您试图传递一个匿名函数。由于吊装过程,您不能这样做。另外,在执行之前没有任何传递给此函数,因此它返回未定义。

【讨论】:

    【解决方案2】:

    地图回调范式的术语一开始可能有点混乱。

    map 方法(例如 Array.map())不是映射函数/回调。这是一个循环,将回调函数应用于数组的每个项目。

    回调执行映射 - 它将数组 item 映射(或转换)为另一个值。

    因此,您的 callback() 函数应该将单个数组项(不是数组)作为参数,并返回一个数组项。 map 函数为数组中的每个项目调用回调,并将结果组装到一个新数组中。 (或者,它可以返回一个对象,或更改原数组)。

    例如:

    var mymap = function(array, callback) {
        var rv = [];
        for(var i=0; i < array.length ; i++) {
            rv.push(callback(array[i]));
        }
        return rv;
    }
    
    mycopy = function(element) {
        return element;
    }
    

    然后你可以使用 map 来复制 MyArray 的一个实例:

    var oldarray = [...];
    
    var newarray = mymap(oldarray, mycopy);
    

    所有这一切的重点是您可以轻松地将mycopy() 替换为更有用的东西,包括在别处定义的函数或内联匿名函数:

    var positives = mymap(oldarray, Math.abs);
    

    【讨论】:

      【解决方案3】:

      .push() 当前直接从myForEach() 接收其值,它不包含用于提供值的return 语句(因此,它默认返回undefined)。

      cb.push() 之间,myForEach() 正在接收每个cb() 的结果并将它们丢弃而不是提供给myMap()

      为避免这种情况,您需要移动这些步骤,以便 .push()cb() 立即相互关联:

      mapped.push(cb(elem, i, arr));
      

      您仍然可以使用myForEach(),而是将其移动到此处以执行迭代,因此每个elem 都可以由cb 处理并推送到mapped

      function myMap(arr, cb) {
        var mapped = [];
      
        myForEach(arr, function (elem, i, arr) {
          mapped.push(cb(elem, i, arr));
        });
      
        return mapped;
      }
      

      【讨论】:

        【解决方案4】:

        mapforEach 的回调是“我应该如何处理每个元素”- 你在myMap 的每个元素中所做的事情与在myForEach 的每个元素中不同.

        myMap 内部,你想这样做:对于arr 的每个元素,调用myMap 的回调,然后将结果推送到结果数组中。(强调部分是 myForEach 回调,您每次都需要使用 myMap 才能正常工作)。

        同时,如果你想将[1, 2, 3] 映射到[0, 2, 6]myMap 回调就是multiply each element with its index and return that value。所以你绝对需要两个不同的回调。

        总之,

        myForEach(arr, function(element, i, ary) { mapped.push(cb(element, i ary)); });

        【讨论】:

        • @david25272:是的,说得不好。
        【解决方案5】:

        这条线有点意思:

        mapped.push(myForEach(arr, cb));
        

        您只是将一个“未定义”值(这是“myForEach”函数返回的值)添加到一个空数组中。

        【讨论】:

        • 是的,我想通了 - 知道 myForEach 返回未定义。您可以在上面看到我对修订的评论。基本上不得不切换一些回调并在它们之间嵌入.push() 函数。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-01-02
        • 2014-07-14
        • 1970-01-01
        • 2016-01-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多