是否有可能进行销毁?

时间:2020-02-17 01:00:18

标签: javascript destructuring

我是解构的新手,需要寻求最佳解决方案的帮助。我有一个非常复杂的对象作为响应返回,并希望对其进行清理。不做任何事情,它看起来像这样:


const homeTeam = {

totalPlaysFor: res.data.stats.home.teamStats[0].miscellaneous.offensePlays,

totalPlaysAgainst: res.data.stats.away.teamStats[0].miscellaneous.offensePlays

}

我知道我可以做类似的事情:


const { offensePlays } = res.data.stats.home.teamStats[0].miscellaneous;

但这只会解决其中一个问题,而另一个问题又会很难阅读。

3 个答案:

答案 0 :(得分:1)

您可以预先解构stats属性,然后创建一个辅助函数,该函数使用.home.away对象并导航到嵌套的.offensePlays

const { stats } = res.data;
const getOffPlays = obj => obj.teamStats[0].miscellaneous.offensePlays;
const homeTeam = {
  totalPlaysFor: getOffPlays(stats.home),
  totalPlaysAgainst: getOffPlays(stats.away)
};

如果没有独立的帮助程序功能,您还可以通过.map ping属性数组(例如[['totalPlaysFor', 'home'], ['totalPlaysAgainst', 'away']])并将其传递给Object.fromEntries来创建对象,但这将是非常重要的IMO可读性较低。

答案 1 :(得分:-1)

您可以根据需要随意破坏!

const homeTeam = {
  totalPlaysFor: res.data.stats.home.teamStats[0].miscellaneous.offensePlays,
  totalPlaysAgainst: res.data.stats.away.teamStats[0].miscellaneous.offensePlays
}

您甚至可以在此处使用数组销毁/对象销毁的组合:

const [ home ] = res.data.stats.home.teamStats
const [ away ] = res.data.stats.away.teamStats

const { offensePlays: totalPlaysFor } = home.miscellaneous
const { offensePlays: totalPlaysAgainst } = away.miscellaneous

const hometeam = { totalPlaysFor, totalPlaysAgainst }

或者,如果您想要更可重用的解决方案,则可以使用参数解构:

const getTeam = (
  { miscellaneous: { offensePlays: totalPlaysFor } },
  { miscellaneous: { offensePlays: totalPlaysAgainst } }
) => ({
  totalPlaysFor,
  totalPlaysAgainst
})

然后您可以像使用它一样

const [ home ] = res.data.stats.home.teamStats
const [ away ] = res.data.stats.away.teamStats
const homeTeam = getTeam(home, away)

答案 2 :(得分:-1)

虽然您可以通过类似的方式直接将其破坏

const {
  data: {
    stats: {
      home: {
        teamStats: [{
          miscellaneous: {
            offensePlays: totalPlaysFor
          }
        }]
      },
      away: {
        teamStats: [{
          miscellaneous: {
            offensePlays: totalPlaysAgainst
          }
        }]
      }
    }
  }
} = res

const homeTeam = {totalPlaysFor, totalPlaysAgainst}

感觉很难看。

无论您是否认为代码丑陋,我都会看到一个更为重要的问题:当这些属性中的任何一个都不存在时,它就不起作用。为了解决这个问题,您可能希望某个功能在该语言中尚不普及,Optional Chaining中的一个功能可以避免为诸如'data?.stats?.home?.teamStats?.0?.miscellaneous?.offensePlays'之类的嵌套路径抛出错误,如果其中一个是undefined提到的节点不存在。

许多库中都可以使用等效功能。 UnderscorepropertylodashpropertyRamdapath提供了稍微不同的版本。 (免责声明:我是Ramda的作者。)但是编写我们自己的书很容易:

const getPath = (pathStr) => (obj) =>
  pathStr .split ('.')
    .reduce ((o, p) => (o || {}) [p], obj)

const res = {data: {stats: {home: {teamStats: [{miscellaneous: {offensePlays: "foo"}}]}, away: {teamStats: [{miscellaneous: {offensePlays: "bar"}}]}}}}

const homeTeam = {
  totalPlaysFor: getPath ('data.stats.home.teamStats.0.miscellaneous.offensePlays') (res),
  totalPlaysAgainst: getPath ('data.stats.away.teamStats.0.miscellaneous.offensePlays') (res)
}

console .log (homeTeam)

请注意,在此简单版本中,数组不是用[0]来描述,而是用.0来描述。显然,如果需要的话,我们可以使它更加复杂。