为什么以下map函数会生成未定义的对象?

时间:2017-06-19 06:30:12

标签: javascript loops

我有一个如下所示的数组context.buildingFields.finished

[{ name: 'a' type: 'text', value: '1' }, { name: 'b' type: 'file', value: '2' }] 

我有一个循环遍历该数组的函数来创建一个新的context.createPanoramasPayload,只有 类型为file的字段:

function handleCreatePanoramas (uploadedPhoto, context, callback) {
    const panoramasFields = context.buildingFields.finished
    context.createPanoramasPayload = panoramasFields.map(field => {
      if (field.type !== 'file') return
      return {
        name: 'index',
        value: uploadedPhoto
      }
    })
    callback(context.createPanoramasPayload)
  }
}

我以为我会生成这样的东西(比如只有一个file类型的字段):

[{ name: 'b' type: 'file', value: '2' }] 

但是,我得到的是这样的:

[undefined, { name: 'b' type: 'file', value: '2' }] 

这是为什么?以及如何修改代码以实现我想要的目标?

3 个答案:

答案 0 :(得分:3)

map返回一个与给定数组长度相同的数组。这对return没有帮助,因为它会在映射数组中生成undefined值。相反,您需要首先应用filter

context.createPanoramasPayload = panoramasFields.filter(field => {
    return field.type === 'file';
}).map(field => {
    return {
        name: 'index',
        value: uploadedPhoto
    }
})

这与功能性编程方式保持一致。

作为旁注,由于回调函数现在除了返回一些东西之外什么都不做,你可以使用箭头函数的表达式语法:

context.createPanoramasPayload = panoramasFields
    .filter(field => field.type === 'file')
    .map(field => ({
        name: 'index',
        value: uploadedPhoto
    }));

答案 1 :(得分:0)

您在这里使用 map 功能,这意味着它不会减少数组的长度。它返回相同长度的数组。因此,使用过滤器来获取结果。

答案 2 :(得分:0)

这个答案是@ trincot答案的延伸。

使用.filter + .map没有错,但它会增加额外的迭代次数。这两个函数都有自己的特定用例,但是当你需要同时执行这两个函数时,.reduce更适合,因为你可以手动解析对象并返回自定义数组/对象

<强>示例

context.createPanoramasPayload = panoramasFields.reduce(function(p, c) {
  if (c.type === 'file')
    p.push({
      name: 'index',
      value: uploadedPhoto
    });
  return p;
}, [])

另请注意使用匿名函数而不是箭头函数=>)。

箭头函数的作用是将当前上下文绑定到传递的回调函数,以便我们可以在回调中使用this。如果您正在使用箭头功能但不在回调中使用this,那么您就是在浪费引擎将绑定上下文放入回调中的努力。因此,如果您不使用this,根据我的理解,最好使用匿名函数而不是箭头函数。

虽然没有错,但在我的POV中,这是一个不好的做法。