【问题标题】:Document mid-function optional parameters记录中间函数可选参数
【发布时间】:2015-02-12 23:21:03
【问题描述】:

是否有适当的语法来记录可选的 JavaScript 参数,其中可选参数位于函数头的中间(想想 jQuery、Gulp 等)

我已经以标准方式记录了该功能,并且效果很好。问题是当我尝试将第二个参数设置为最后一个变量(在未使用可选参数的情况下)时,我的 IDE 会感到困惑。

例子:

/**
 * @param {number} a_num
 * @param {string} [a_str='']
 * @param {{}} a_obj
 */
function (a_num, a_str, a_obj) {
    if (!a_obj) a_obj = a_str; // doesn't want me to save a string to an object.
    a_str = '';
    // more stuff
}

如果重要的话,我使用的是 JetBrains 的 PHPStorm,它主要使用 Google Closure 文档样式。虽然我正在寻找更通用的最佳实践方法。

我怀疑我可以做一些丑陋的事情,比如:

/**
 * @param {number} a_num
 * @param {string|{}} a_str
 * @param {{}} [a_obj=null]
 */

但这并不能像我想的那样准确地描述这种情况。我希望,因为这正在成为一种常见的结构,所以有一些东西可以正确处理。

【问题讨论】:

  • 我有两张反对票,还有一次因为不清楚而试图关闭。我知道函数头中间的可选参数在大多数语言中是禁忌(或完全不可能),但在 JavaScript 中它是一种有效且经常使用的模式,所以我认为这是一个有效的问题。至于不清楚,如果有人可以发表评论让我知道不清楚的地方,我很乐意更新这个问题。谢谢。
  • 你可以在 javascript 中做很多事情,但仅仅因为语言允许它并不意味着它是好的做法。例如,javascript 允许使用全局变量,而许多语言则不允许,这并不意味着在 JS 中使用大量全局变量是个好主意。
  • 我已经删除了我的答案,因为它并没有真正回答你的问题,但我在这里添加它作为评论,因为我认为它仍然是对话的相关部分:我认为把参数列表中间的可选参数。它可能会增加 API 用户的困惑。而是考虑将可选参数放在参数的末尾,或者传入一个选项对象而不是参数列表。
  • @bhspencer:很公平,我也不完全不同意你的观点。我认为它有助于整体清晰的一个有效用例是当最后一个参数是回调时,它允许更清晰、更容易读取传入的匿名函数。谢谢。
  • @bhspencer 我也同意这一点。但是,匿名回调有一些有效的时间和地点。我正在考虑的特定实例,也恰好是我问这个问题的函数的用例,是用于 gulp 任务中的函数。 Gulp 任务通常很简单,并且该函数永远不需要重用。在这种情况下使用回调可以提高可读性。

标签: javascript google-closure jsdoc jsdoc3


【解决方案1】:

在函数的参数列表中间注释可选参数几乎与维护使用这种类型的方法签名的代码一样具有挑战性。

  1. Javascript 并不真正支持函数参数列表中间的可选参数(要做到这一点,您需要命名参数)。相反,宣传这一点的函数会尝试根据参数的数量和值来辨别调用了哪个版本的函数。

  2. Javascript 也不支持函数重载。

认识到这些限制为支持本质上是文档策略的内容提供了第一条线索。您的注释必须支持所有类型的调用 - 这样做会在使用强制或检查类型的工具时失去一定程度的类型安全性。

让我们以jQuery.prototype.bind 签名之一为例:

jQuery.prototype.bind( eventType [, eventData ], handler )

要记录此方法,我们认识到始终需要两个参数。首先让我们重新排列和重命名参数:

jQuery.prototype.bind( eventType, eventDataOrHandler, [ handler ] )

通过这种重新排列,JSDoc 变得更加清晰:

/**
 * @param {string} eventType
 * @param {(*|function(Event))} eventDataOrHandler
 * @param {function(Event)=} handler
 * @return {!jQuery}
 */
jQuery.prototype.bind =
    function(eventType, eventDataOrHandler, handler) {};

不幸的是,没有办法指定使用三个参数时需要一组类型,而使用两个参数时需要另一组类型。

细读Closure-compiler jQuery externs 会给你很多例子。

【讨论】:

  • 谢谢。我已经这么想了。希望有更神奇的东西,但完全有道理。幸运的是,我记录的只是一个功能,所以还不算太糟糕。
  • @doc 我很确定人们不喜欢我的问题的想法,并且很难区分不喜欢问题(和答案)的内容与写得不好的问题。跨度>
猜你喜欢
  • 1970-01-01
  • 2018-06-27
  • 1970-01-01
  • 2020-12-12
  • 2019-01-11
  • 1970-01-01
  • 1970-01-01
  • 2013-01-08
  • 2012-10-15
相关资源
最近更新 更多