【问题标题】:Calculation result wrong in Extendscript JavascriptExtendscript Javascript中的计算结果错误
【发布时间】:2016-08-30 23:09:16
【问题描述】:

我正在编写一个 InDesign 脚本,并且我正在使用 moment.js 来计算日期。

当我使用日期格式“Do”时,它应该返回例如“1st, 2nd, 3rd, 4th...”,但是函数执行的计算返回错误的结果,结果是这样的:

第一名 第 2 次 第三 第 4 名 第 5 名 6日 7日 8日 9日 10日 11日 12日 13日 14日 15日 16日 17日 18日 19日 20日 21日 22日 23日 24日 25日 26日 27日 28日 29 日 30 日 31日

这是函数:

function returnOrdinal(number) {
  var b = number % 10,
  output = (parseInt(number % 100 / 10) === 1) ? 'th' :
   (b === 1) ? 'st' :
   (b === 2) ? 'nd' :
   (b === 3) ? 'rd' : 'th';
  return number + output;
}

我创建了一个JSFiddle,它使用相同的函数并返回正确的结果。

那么这是 Extendscript 中的一个已知问题吗?你知道返回序数的其他方法吗?有什么解决方法吗?

提前致谢

【问题讨论】:

  • 您就不能通过一个有问题的输入单步执行,看看哪里出错了吗?

标签: javascript adobe-indesign extendscript


【解决方案1】:

ExtendScript 似乎不支持链式三元运算符。据我所知,它是 ECMA 3。在 InDesign 中工作的另一个选项 - 只需使用 if else 或 switch

function returnOrdinal(number) {
    var b = number % 10;
    var output;
    if (parseInt(number % 100 / 10) === 1) {
        output = 'th';
    } else {
        switch (number) {
            case 1:
                output = 'st';
                break;
            case 2:
                output = 'nd';
                break;
            case 3:
                output = 'rd';
                break;
            default:
                output = 'th';
        }
    }
    return number + output;
}

【讨论】:

  • 奇怪的问题是它不会抛出错误,而是返回错误的结果。 (我希望出现错误而不是错误的结果)。您的函数和上述其他答案中的函数有效,但这仍然不能完全回答我的问题,因为我想知道为什么 Extendscript 返回错误值以及这是否是 Extendscript 中的一个已知问题。我将使用this function,因为它是最精简的版本并且完美运行!
  • 我刚刚找到this thread,有人报告了与链式三元运算符相同的问题,所以看起来你是对的,这是 Extendscript 处理错误的问题......所以我要批准你的回答!如果您可以在扩展脚本中提供有关此错误的更多信息来改进您的答案,那就太好了!
  • 您发布的链接表明问题出在 ESTK 上。我尝试了两种不同版本的 ESTK,结果是一样的。另一方面,我尝试在没有 ESTK 的 InDesign 和 InDesign Server 上运行脚本,但结果仍然不正确。我相信,问题实际上是 ECMA 3 或扩展脚本实现
【解决方案2】:

您的代码也适用于http://www.w3schools.com/tags/tryit.asp?filename=tryhtml_basic,因此我怀疑回调环境会产生副作用。我建议尝试另一种可能对副作用不太敏感的写作。

function returnOrdinal(number) {
  switch((number % 100 / 10).toFixed(0) == 1?0:number%10) {
  case 1:  return number+'st';
  case 2:  return number+'nd';
  case 3:  return number+'rd';
  default: return number+'th';
  }
}

【讨论】:

  • 谢谢!你的功能有效。我也刚刚尝试使用this function here,它看起来非常整洁,并且被 Shopify 使用!我仍然不明白为什么你和我链接的函数可以工作,而我发布的那个 - 这是 moment.js 使用的函数 - 没有......
【解决方案3】:

根据文档,您的结果是正确的,而您的代码是错误的(令人惊讶的是,这意味着您使用其他 JavaScript 引擎进行的测试也是错误的)。

ECMAScript 中的通用运算符关联性是从左到右的。但是,三元测试是right to left。这意味着您的

output = (b === 1) ? 'st' : (b === 2) ? 'nd' : (b === 3) ? 'rd' : 'th';

(稍微简化)首先选择(b === 1),可能的结果是'rd''th'——最后两个。

另见Mozilla's reference? .. : 的示例用法,其中明确提到了关联性:

也可以进行多次三元求值(注意:条件运算符是右结合的):

var firstCheck = false,
    secondCheck = false,
    access = firstCheck ? "Access denied" : secondCheck ?
    "Access denied" : "Access granted";

console.log( access ); // logs "Access granted"

用括号覆盖优先级使其按预期工作:

function returnOrdinal(number) {
  var b = number % 10,
  output = (parseInt(number % 100 / 10) === 1) ? 'th' :
    ((b === 1) ? 'st' :
    ((b === 2) ? 'nd' :
    ((b === 3) ? 'rd' : 'th')));
  return number + output;
}

【讨论】:

  • 对不起,Rad,但我认为这是一个错误的答案。我不认为 JSFiddle 和其他一些类似的引擎会产生不好的结果,因为我确信他们使用 JavaScript 来评估它。我将发布一些代码作为支持我的案例的另一个答案。
  • @NicolaiKant:我对从右到左的解释是错误的吗?我确保在 InDesign 中测试了原始代码和调整后的代码(强制优先)。
  • 不,带括号的解决方案在 InDesign 中运行良好。我没有批评您的代码,而是质疑将问题与三元运算符的从右到左测试联系起来。我认为它会产生与 JSFiddle 相同的结果。我用一个简单的示例代码发布了另一个答案来证明我的观点。所有 JS 引擎都按照 OP 最初建议的方式渲染它,所以我认为你的逻辑不正确,对不起。
【解决方案4】:

为了反驳 Rad Lexus 的回答,建议 JSFiddle 和 InDesign 给出正确的答案存在问题。

我有以下测试页面:

<html>

<head>
    <script>
        function test(num) {
            var b = num;   
            var output = (b === 1) ? 'st' : (b === 2) ? 'nd' : (b === 3) ? 'rd' : 'th';    
            document.getElementById("ordinals").innerHTML = b + output;    
        }
    </script>
</head>

<body onload="test(1);">
    <div id="ordinals">test
    </div>
</body>

</html>

Rad 的帖子建议根据文档,这应该评估为 '1rd','2rd','4rd'。我将它保存为一个页面并在 Chrome、IE 和 Safati 中加载。这三个都给了我第 1、第 2 和第 4 作为输出,以响应 1,2 和 4 作为输入。

您可以发布一些代码来支持您的答案吗?根据您的说法,vanilla JavaScript 引擎有问题或文档中有错误。

【讨论】:

  • 在 InDesign 中测试过。不过,为了确定,我稍后会用另一个版本重新运行测试。我完全接受 Adob​​e 自己的内部 JS 引擎可能会受到指责的建议。至少,这可以解释各种实现的不同结果。
  • 好吧,看来我判断拉德的回答太快了!它得到了很好的解释和记录,我只是认为它是正确的..!感谢@NicolaiKant 的努力!好像我在 Extendscript 中遇到了一些很少发生的错误...
  • 重要的是,您知道问题出在哪里,并且这里建议了一些好的解决方法。 Rad 还强调了一些我不知道的东西。
  • Rad,根据我的经验,如果某些东西不起作用,那是 Adob​​e 实施的问题。我认为,他们基于 ECMA 3 的实现,甚至没有完全实现并且存在一些错误和问题。据我记忆,引擎已经有一段时间没有更新了,虽然我没有使用最新版本的 Adob​​e 产品。
【解决方案5】:

这条线可以工作吗?

String(number).replace(/1$/, "1st").replace (/2$/, "nd").replace(/3$/, "rd").replace(/[4-9]$/, "th");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-20
    • 2019-05-22
    • 1970-01-01
    • 2011-07-30
    • 2020-12-29
    • 2022-11-30
    相关资源
    最近更新 更多