【问题标题】:Compiled CoffeeScript Uncaught TypeError编译的 CoffeeScript 未捕获的 TypeError
【发布时间】:2013-08-27 19:19:59
【问题描述】:

我正在尝试将以下 CoffeeScript 代码编译成 Javascript:

GetCard = ->
  do Math.floor do Math.random * 12

Results = ->
  do NewGame if prompt "You ended with a total card value of #{UserHand}. Would you like to play again?"
  else
    alert "Exiting..."

NewGame = ->
  UserHand = 0
  do UserTurn

UserTurn = ->
  while UserHand < 21
    if prompt "Would you like to draw a new card?" is "yes"
      CardDrawn = do GetCard
      UserHand += CardDrawn
      alert "You drew a #{CardDrawn} and now have a total card value of #{UserHand}."
    else
      do Results
      break

但是如果你说是,生成的 Javascript 会在控制台打印以下错误:

Uncaught TypeError: number is not a function BlackJack.js:4
GetCard BlackJack.js:4
UserTurn BlackJack.js:22
NewGame BlackJack.js:14
onclick

CoffeeScript 也没有将 UserHand 设置为 0 出于某种原因。我对 Javascript 相当陌生,对 CoffeeScript 也很陌生。我四处搜索并阅读了 CoffeeScript 文档以及 CoffeeScript Cookbook,据我所知,CS 代码看起来是正确的,而 JS 则不然:

var GetCard, NewGame, Results, UserTurn;

GetCard = function() {
  return Math.floor(Math.random() * 12)();
};

Results = function() {
  return NewGame(prompt("You ended with a total card value of " + UserHand + ". Would you like to play again?") ? void 0 : alert("Exiting..."))();
};

NewGame = function() {
  var UserHand;
  UserHand = 0;
  return UserTurn();
};

UserTurn = function() {
  var CardDrawn, _results;
  _results = [];
  while (UserHand < 21) {
    if (prompt("Would you like to draw a new card?") === "yes") {
      CardDrawn = GetCard();
      UserHand += CardDrawn;
      _results.push(alert("You drew a " + CardDrawn + " and now have a total card value of " + UserHand + "."));
    } else {
      Results();
      break;
    }
  }
  return _results;
};

任何帮助将不胜感激。谢谢!

更新: 感谢所有的答案。我只是对双括号有点困惑,错误地使用 do 关键字替换参数括号而不是函数调用括号。不过,我仍然对全球范围感到困惑。我知道您可以在纯 JS 中使用 var 关键字,但在 CoffeeScript 文档中它指定您永远不需要使用它,因为它为您管理范围?

【问题讨论】:

  • 问题在这里:Math.floor(Math.random() * 12)()(注意尾括号)。至于为什么coffeescript会添加这个,我不知道(我不熟悉它)。猜测一下,可能是因为您在该行中有 2 个 do 关键字?
  • 也是设置UserHand,但它是NewGame的局部变量。我猜你打算将它作为一个全局变量。再说一次,我不熟悉 coffeescript,所以我不知道你需要在那里做什么。
  • 如果您是 JavaScript 新手,请远离 CoffeeScript。
  • 谢谢!将 GetCard 语句更改为使用括号而不是 do 关键字有效。而且我还没有弄清楚为什么 CS 将 UserHand 设置为局部变量......也许其他人会插话。

标签: javascript coffeescript


【解决方案1】:

经过一番阅读,您的第一个问题似乎是因为 do 运算符。据我所知,它用于在循环中创建闭包以将当前值绑定到函数。这不是你需要的。

我不认为简单的有什么问题:

GetCard = ->
    Math.floor( Math.random() * 12 )

第二个问题是范围之一。 UserHandNewGame 的本地地址,因此在 UserTurn 中无法访问(那里是 undefined)。您可以将其设为全局,或将其作为参数传递,但在我看来 NewGame 无论如何只需要结果:

NewGame = ->
    hand = UserTurn() // set hand to whatever the UserHand is from UserTurn

UserTurn = ->
    UserHand = 0
    while UserHand < 21
        if prompt "Would you like to draw a new card?" is "yes"
        (etc)
    UserHand // return the final UserHand value after the loop

我还建议重新考虑一些名称;有些有点令人困惑。虽然你已经在许多好的地方分解了它,但仍然有一些奇怪的选择(例如,为什么超过 21 由 UserTurn 处理但停止由另一个函数处理?)

【讨论】:

    【解决方案2】:
    GetCard = ->
      Math.floor(Math.random() * 12)
    

    您需要那里的括号来说明您要调用 Math.random 而不使用任何参数。否则,functionName something 的意思是“调用 functionName 并将某些东西作为第一个参数”。

    一般来说,只有在函数调用非常明显时才省略括号,否则它是一个模棱两可的东西,会妨碍可读性。

    好的:

    someFunc 1, 2, 3
    

    不清楚:

    someFunc someOtherFunc someArg
    

    (除了...)

    您应该查看do 关键字。它仅对非常特定的目的有用,并且您几乎所有的使用都是不必要/不正确的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-07
      • 2014-05-22
      相关资源
      最近更新 更多