Extendscript Javascript中的计算结果错误

时间:2016-08-29 20:22:15

标签: javascript adobe-indesign extendscript

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

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

1RD 2RD 第3 第四 第5 第6 7日 第八 9日 10rd 11rd 12RD 第13 14rd 15rd 16rd 17RD 18rd 19rd 20 21rd 22rd 第23 第24 第25 第26 第27 第28 第29 第30 31rd

这是功能:

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;
}

我创建了一个使用相同功能的through google apps script,它会返回正确的结果。

这是Extendscript中的已知问题吗?你知道还有其他方法可以归还顺序吗?任何解决方法?

提前致谢

5 个答案:

答案 0 :(得分:3)

您的代码也适用于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';
  }
}

答案 1 :(得分:3)

看起来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;
}

答案 2 :(得分:1)

根据文档,您的结果是正确的,并且您的代码是错误的(令人惊讶的是,这意味着您使用其他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;
}

答案 3 :(得分:1)

对抗Rad雷克萨斯的回答,表明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引擎存在问题或文档中存在错误。

答案 4 :(得分:0)

这条线可以工作吗?

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