编译的CoffeeScript Uncaught TypeError

时间:2013-08-25 01:41:18

标签: javascript coffeescript

我正在尝试将以下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文档中,它指定你永远不需要使用它,因为它管理你的范围?

2 个答案:

答案 0 :(得分:1)

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

我认为简单地说没有任何问题:

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

第二个问题是范围之一。 UserHand位于NewGame的本地,因此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处理但由另一个函数停止处理?)

答案 1 :(得分:0)

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

你需要那里的parens来澄清你想要调用 Math.random而没有参数。否则functionName something表示“以某个东西作为第一个参数调用functionName”。

一般情况下,只有当函数调用显而易见时,才会省略函数调用,否则会妨碍可读性。

行:

someFunc 1, 2, 3

不清楚:

someFunc someOtherFunc someArg

(除了...)

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