简体   繁体   English

编译的CoffeeScript未捕获的TypeError

[英]Compiled CoffeeScript Uncaught TypeError

I am trying to compile the following CoffeeScript code into Javascript: 我正在尝试将以下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

But the resulting Javascript prints the following errors to the console if you say yes: 但是,如果您说是,则生成的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 is also not setting UserHand to 0 for some reason. 由于某些原因,CoffeeScript也未将UserHand设置为0 I am fairly new to Javascript and very new to CoffeeScript. 我对Java相当陌生,对CoffeeScript也很陌生。 I've searched around and read the CoffeeScript docs as well as the CoffeeScript Cookbook and as far as I can tell the CS code looks correct, while the JS doesn't: 我到处搜索并阅读了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;
};

Any help would be greatly appreciated. 任何帮助将不胜感激。 Thanks! 谢谢!

Update: Thanks for all the answers. 更新:感谢您提供所有答案。 I just got a little confused on the double parentheses and mistakenly used the do keyword to replace the parameter parenthesis instead of the function call parenthesis. 我只是对双括号有些困惑,并错误地使用do关键字替换了参数括号而不是函数调用括号。 I'm still confused on the global scope though. 我仍然对全球范围感到困惑。 I know you can use the var keyword in plain JS, but on the CoffeeScript docs it specifies that you should never need to use it, as it manages scope for you? 我知道您可以在纯JS中使用var关键字,但是在CoffeeScript文档中,它指定您永远不需要使用它,因为它可以为您管理范围?

After a little reading, it seems your first problem is because of the do operator. 稍作阅读后,看来您的第一个问题是因为do运算符。 As far as I can tell, it is for creating closures within loops to bind current values to functions. 据我所知,它是在循环内创建闭包以将当前值绑定到函数。 Not what you need here. 不是您这里需要的。

I don't think there's anything wrong with simply: 我不认为简单存在任何问题:

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

The second issue is one of scope. 第二个问题是范围之一。 UserHand is local to NewGame , so it isn't accessible in UserTurn (it is undefined there). UserHand是本地NewGame ,所以它不是在访问UserTurn (这是undefined存在)。 You could make it global, or pass it as a parameter, but it looks to me like NewGame only needs the result anyway: 您可以将其设置为全局,也可以将其作为参数传递,但是在我看来, 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

I'd also suggest rethinking a few names; 我也建议重新考虑一些名字; some are a little confusing. 有些有点混乱。 And while you've broken it up at many good points, there are still some odd choices (eg why is going over 21 handled by UserTurn but stopping handled by another function?) 尽管您在很多方面都进行了分解,但仍然有一些奇怪的选择(例如,为什么UserTurn处理了21个以上的UserTurn而停止了另一个函数的处理?)

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

You need the parens there to clarify that you want to invoke Math.random with no arguments. 您需要那里的括号以澄清您Math.random带任何参数调用 Math.random Otherwise a functionName something means "invoke functionName with something as the first argument". 否则, functionName something表示“以某些内容作为第一个参数调用functionName”。

In general, only omit parens for function calls when it is dead-obvious, otherwise it is an ambiguous thing that hampers readability. 通常,只有当函数调用变得明显时,才忽略对函数的调用,否则它会影响可读性。

OK: 好:

someFunc 1, 2, 3

Unclear: 不清楚:

someFunc someOtherFunc someArg

(aside...) (在旁边...)

You should review the do keyword. 您应该查看do关键字。 It is only useful for a very specific purpose and almost all of your uses are unnecessary/incorrect. 它仅对非常特定的用途有用,并且几乎所有的使用都是不必要/不正确的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM