简体   繁体   中英

Compiled CoffeeScript Uncaught TypeError

I am trying to compile the following CoffeeScript code into 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:

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. I am fairly new to Javascript and very new to 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:

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. 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?

After a little reading, it seems your first problem is because of the do operator. 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). You could make it global, or pass it as a parameter, but it looks to me like NewGame only needs the result anyway:

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?)

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

You need the parens there to clarify that you want to invoke Math.random with no arguments. Otherwise a functionName something means "invoke functionName with something as the first argument".

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. It is only useful for a very specific purpose and almost all of your uses are unnecessary/incorrect.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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