建立回退链的最干净的方法?

Cleanest way to set up a chain of fallbacks?

因此,我正在对来自 Google 个地点 API 的地址进行地理编码。有 38 种 Google 地址组件类型,我们有 ~5 种内部地址组件类型,所以我需要一个系统来将许多 Google 类型映射到我们的内部类型,并带有回退。

例如:

var neighbourhood = googleResponse.neighborhood || googleResponse.sublocality_level_2 || googleResponse.sublocality_level_1

执行此操作的 best/cleanest/most 有效方法是什么?基本上,我需要为某个返回值分配一个 var,除非该返回值未定义,然后向下移动链。

我认为您的方法是合理的 - 使用短路 OR 感觉比使用某种分支语句要干净得多。我的两个建议是:

  • 您可能应该添加某种硬编码值(也许是一个空字符串?取决于您的用例)作为最后的回退,这样如果找不到所有选项,您就不会最终变量被设置为意想不到的东西。我认为 100% 明确所有可能返回的东西始终是一个好习惯。
  • 我建议将该逻辑拉出到一个函数中,这样如果您想在其他地方重用它,它将更易于维护。即使您认为您不需要再次使用它,它仍然是值得的,以防您以后改变主意 - 必须检查并替换一段代码的每个实例是非常乏味的!它还使您的代码更容易测试 - 您可以传入硬编码 googleResponse 并检查输出是否符合您的预期。

所以我的方法可能看起来像这样:

function getNeighborhood(googleResponse) {
    return googleResponse.neighborhood
        || googleResponse.sublocality_level_2
        || googleResponse.sublocality_level_1
        || "";
}

var neighborhood = getNeighborhood(googleResponse);

编辑:

针对您的评论,对于必须连接的值,我可以想到几个选项。

如果只是"everything or nothing"的问题,你可以用三元表达式写得相当优雅:

function getStreet(googleResponse) {
    return googleResponse.street_number && googleResponse.route
        ? googleResponse.street_number + googleResponse.route
        : "";
}

但是,如果您开始尝试使用回退嵌套这些内容,它很快就会变得非常不可读。在这一点上,你最好只依靠 if/else if/else - 它有点啰嗦,但它是可以理解的,在我看来这更重要。

function getStreet(googleResponse) {
    if (googleResponse.street_number && googleResponse.route) {
        return googleResponse.street_number + googleResponse.route;
    }
    else if (/* fallback */) {
        return /* concat here */;
    }
    else {
        // Make sure to always return a value, even if all of
        // the other fallbacks fail!
        return "";
    }
}