6

So, I have the code, its not done, but all i want it to do is display one alert box if I write the word 'help', and say something else if anything else is entered.

function prompter() {
var reply = prompt("This script is made to help you learn about new bands, to view more info, type help, otherwise, just click OK") 
if (reply === 'help' || 'Help')
  {
  alert("This script helps you find new bands. It was originally written in Python 3.0.1, using Komodo IDE, but was then manually translated into Javascript. Please answer the questions honestly. If you have no opinion on a question, merely press OK without typing anything.")
  }
else
  {
  alert("Press OK to continue")
  }
};

but, what happens, is no matter what, the first alert box pops up, even if you press cancel! How should I fix this???

Timothy Jones
  • 21,495
  • 6
  • 60
  • 90
Billjk
  • 10,387
  • 23
  • 54
  • 73

5 Answers5

12
if (reply === 'help' || 'Help')

should be:

if (reply === 'help' || reply === 'Help')

since 'Help' is "truthy" and so the first part of the if will always be entered.

Of course, even better would be to do a case-insensitive comparison:

if (reply.toLowerCase() === 'help')

Example: http://jsfiddle.net/qvEPe/

Andrew Whitaker
  • 124,656
  • 32
  • 289
  • 307
  • 'Help' isn't truthy in this case, because there's no `==` - see my answer. However, 'Help' is true, because strings are 'true' unless there's an `==` operator around. – Timothy Jones Feb 15 '12 at 23:35
  • 2
    @TimothyJones: I'm not sure that's correct. As a non-boolean, `'Help'` can't simply be `true`. It is coerced to `true` upon evaluation, however. In other words, type coercion occurs whether or not an `==` is present. – Andrew Whitaker Feb 15 '12 at 23:41
  • @AndrewWhitaker Yes, strings are coerced to true, unless they're empty. However, the 'truthyness' in Javascript only happens when there's an `==` present (truthyness is caused by the Abstract Equality Comparison Algorithm, which you can find in the ECMAScript Specification, 5th edition 11.9.3). So the string `"0"` is also coerced to true unless there's a `==` around. It's misleading to describe strings generally as truthy or not - since truthyness only happens in `==` comparisons. – Timothy Jones Feb 15 '12 at 23:47
  • 1
    @TimothyJones - I disagree. "Truthyness" is a more general term than you seem to want to make it. Quick example: `var x = 'A' || 'B';` - `x` will be `'A'`, not `true`, so it has not been coerced to `true` even though there's no `==` operator in sight. Surely that's an example of "truthyness"? (Unless you're trying to say it is coerced to `true` while simultaneously retaining its original string value, which is just getting silly.) Also, `0 == "0"` doesn't coerce to `true` even though there's an `==`... – nnnnnn Feb 16 '12 at 00:01
  • @nnnnnn Javascript disagrees - `if(0 == "0") console.log("true");` prints true :) – Timothy Jones Feb 16 '12 at 00:09
  • @nnnnnn (and Andrew) Thanks, I'll update what I think people mean when they say 'truthy'. Seems I had it narrower than everyone else :) – Timothy Jones Feb 16 '12 at 00:15
  • @TimothyJones - The whole _expression_ `0=="0"` evaluates as `true`, not the string within the expression. In this case the actual string `"0"` is coerced to be numeric. Thanks. – nnnnnn Feb 16 '12 at 00:16
2

The problem is here:

if (reply === 'help' || 'Help') // <-- 'Help' evaluates to TRUE
                                //      so condition is always TRUE

The equality operator doesn't "distribute", try

if (reply === 'help' || reply === 'Help')
calebds
  • 25,670
  • 9
  • 46
  • 74
1

The reason why it always pops up is that reply === 'help' || 'Help' evaluates as (reply === 'Help') || ('Help'). The string literal Help is always truthy in Javascript hence it always evaluates to truthy.

To fix this you need to compare reply to both values

if (reply === 'help' || reply === 'Help') {
  ...
}

Or if you want any case variant of help use a regex

if (reply.match(/^help$/i)) {
  ...
}
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
1

Just change this: if (reply === 'help' || 'Help')

To this: if (reply === 'help' || reply === 'Help')

The or statement was not comparing the variable.

Jeffrey Sweeney
  • 5,986
  • 5
  • 24
  • 32
0

The problem is this line:

 if (reply === 'help' || 'Help')

Because in JavaScript, objects and non-empty strings evaluate to true when used as a boolean. There are a couple of exceptions to this when using ==

 if("0") // true
 if("0" == true) // false

In general, it's not a good idea to use == or raw variables in if statements.

As others have pointed out, use

if (reply === 'help' || reply === 'Help')

Or better:

if (typeof reply === 'string' && reply.toLowerCase() === 'help')

instead.

Timothy Jones
  • 21,495
  • 6
  • 60
  • 90
  • Non-empty strings are truthy, not true - otherwise `"string" === true` would evaluate to `true`. – nnnnnn Feb 16 '12 at 00:04
  • @nnnnnn You're right. I had thought that most uses of truthy in Javascript referred to "0" as well, but a quick google showed that's not the case. I'll update it. – Timothy Jones Feb 16 '12 at 00:11