I'm making a simple JavaScript for opening a dialog with a hypothetical recruiter. When I run the script it does not complete, but neither throws any errors or warnings. At least (!) it doesn't seem like it completes, but it might be me not thinking straight about how to use Firebug.
Here's the code:
var str = prompt("How are you today?", "I'm quite alright, thank you")
if (str.search(/\+alright\i|\+good\i|\+fine\i|\+alright\i/) != -1) {
alert("I'm very glad to hear that! Me, I'm feeling freaky today!");
} else if (str.search(/\+not/&&(/\+well|\+good/)||(/\+sad|\+down|\+blue/)) != -1) {
if (confirm("I'm sorry to hear that! Perhaps you'd like to get together and talk sometime?")) {
var sadNumber = prompt("What's your phone number? (The one entered is mine, feel free to call me!)", "072-");
if (sadNumber.search(/\D/) != -1) {
alert("Sorry, I think there's something wrong with your number. Try entering it with just numbers please!");
sadNumber = prompt("What's your phone number? (The one entered is mine, feel free to call me!)", "072-");
} else {
alert("That's fine! Let's move on with our job questions, shall we?");
}
} else if (alert("Wow! I didn't expect that answer! Truly interesting"));
}
Tried methods
This is what it looks like in Firebug:
After running, this is where the statement stops for some reason. Pressing continue breaks and steps out of the statement:
Stepping through, the statement continues to run, but skips all the (I conbsider) important parts. As you can see here, the alert is being skipped, and statements continues at the else if line:
My guess it that my regexp search (either the method, pattern, or modifiers) is wrong and that's why the statement breaks. I'm still finding it odd, though, since regexp errors usually throw errors or warnings, but this script returns none.
Anyone knows why this particular script breaks? Anyone having a good methodology for debugging errors that do not throw errors or warnings?
Your regular expressions are wrong.
This one, for instance: /\+alright\i|\+good\i|\+fine\i|\+alright\i/ searches for +alrighti (literally) or +goodi or +finei or +alrighti, because \+ means a literal + and \i means a literal i.
You probably meant /alright|good|fine/i, which searches for alright, good, or fine, case-insensitve. Or perhaps /\b(?:alright|good|fine)\b/i, which does the same but is expecting word boundaries on either side of the word.
You can test out your regex at various sites, including regex101.com.
Related
Oops, try again. Make sure your string is correct and is between quotation marks!
This is the error that I keep receiving on Part 3: "Adding Some Story" of the second course on Javascript via Codecademy.com--"Code Your Own Adventure".
Here is what I have prior to adding a single line for this section--
confirm("I am ready to get silly!");
var age = prompt("What's your age");
if( age < 13)
{
console.log=("You are allowed to play, but I take no responsibility.");
}
else
{
console.log=("GO GET CRAZY!");
}
Then, the instructions are written as--
Under all your previous code, print out the following introduction, exactly as it is written.
"You are at a Justin Bieber concert, and you hear this lyric 'Lace my shoes off, start racing.'"
Print the introduction using console.log. Remember that the introduction is a string, so make sure to keep it between quotes.
So then I add in:
console.log=("You are at a Justin Bieber concert, and you hear this lyric 'Lace my shoes off, start racing.'");
And I continue to get the same error I mentioned above:
Oops, try again. Make sure your string is correct and is between quotation marks!
This continues to happen no matter what sorts of variations of the "introduction" I try to input. Please help!
Here is a link to the course page of this lesson.
Remove the = in console.log=("...");. console.log() is a method that you can invoke by passing data (in your case, a string) as parameters within the parentheses. = is the assignment operator and it's not used when invoking functions/methods.
console.log is a function. It essentially is the function log in the class console. So if for example you made a class food and a function cook in that class, you'd call it like: food.cook()
With that explained, console.log("...") is the format you want. Exactly how you used prompt("What's your age") just without a return variable.
I would like to know if leaving an empty if statement for certain situations as:
else if(typeof console === 'undefined'){}
Just to have the code bypass the rest of the function It is an accepted and safe way to work or there are other recommendation practices for these cases?. Thank you.
It's fine and safe to leave if branches empty, the only thing I would add is a comment:
else if(typeof console === 'undefined')
{
//explanation why nothing has to go here
}
Without seeing the rest of the code I'm unsure how you're using this to "bypass the rest of the function", there may be a better way to do this.
From what information you've provided me, I can glean that the answer is "no". It will work, but it's bad style. If you would like to bypass the rest of the function, why not return; or put most of the logic in the if statement that pertains to it so that there is no bypassing at all?
I just had a case in which I chose to use an empty if-statement (professional context). I must agree though, there definitely is a technically cleaner solution. Still, since in a professional context time is important too, I chose to use the empty if-statement in my case, so I wanted to share my train of thought with you.
In my case I'm patching existing code with a variable that is used to skip already existing nested if-statements. The main function keeps running before and after the statement.
Original Code:
if(bValidateA){
}elseif(bValidateB){
}elseif(bValidateC){
}
// ... code continues with variables set inside the statements.
Now we want to add a global Parameter to not validate anything. What are my options and why do they suck?
Solution A sucks because much work and less easy to read:
if(!bValidateNothing && bValidateA){
}elseif(!bValidateNothing && bValidateB){
}elseif(!bValidateNothing && bValidateC){
}
Solution B sucks because empty if-statement:
if(bValidateNothing){
// empty
}elseif(bValidateA){
}elseif(bValidateB){
}elseif(bValidateC){
}
Solution C sucks because it becomes too nested (in my case there have been some additional ifs in the original code):
if(!bValidateNothing){
if(bValidateA){
if(xx){
}elseif(xy){}
}elseif(bValidateB){
}elseif(bValidateC){
}
}
Solution D, the technically cleanest solution by adding additional functions, sucks because you need to split your code, which needs a lot of time, and may result in new errors.
(no pseudocode)
So, to answer the question "accepted and safe": it works, it's readable, safe and quick. Sometimes that has to be enough, considering the alternatives. If you have the time to avoid using it, I'd probably still recommend that instead.
Funny enough, the time I saved by using this quick way to implement my logic, has now been successfully spent adding my cents to this ten year old already answered question.
Just don't write a block for a case you don't want to handle.
If you only want to do something when console exists, then do that:
if(typeof console !== 'undefined'){
// your code
}
// else if(typeof console === 'undefined'){}
// you don't need that second part
Or maybe I didn't quite get your issue?
Same as Pioul's answer, but I'd add that imo checking existence in javascript looks much tidier with the !! (notnot) operator.
if(!!console){
// your code
}
// else if(!console){}
// you don't need that second part
Sometimes it is useful to have debugging information printed out:-
if(typeof console !== 'undefined'){
console.log("debug info");
}
Then, before releasing the code, simply comment out all the console.log's
// console.log("debug info");
This can be done with a macro.
It will leave an empty if statement. But this is not a compilation error so that's OK.
Note, that if you're going to comment out the line it is important that braces are used. Otherwise you'd have the next line dependent on the if statement which would be a bleeding shame.
Using an empty if statement can be a valid and accepted practice in certain situations.
For example, when working with a try-catch block, you may use an empty if statement to handle specific errors without disrupting the rest of the function. Additionally, it can be used for performance optimization by short-circuiting the evaluation of certain conditions.
Make sure that when using an empty if statement, it is properly commented to provide context and explanation for its use.
Example:
try {
// code that may throw an error
} catch (error) {
if(error instanceof SpecificError) {
// handle specific error without disrupting the rest of the function
}
}
Another example:
if(isFirstConditionTrue && isSecondConditionTrue && isThirdConditionTrue) {
// Do something
} else if(isFirstConditionTrue && isSecondConditionTrue) {
// Do nothing, because third condition is false
} else {
// handle other conditions
}
It's always a good practice to add comments explaining the purpose of each empty if statement and why you chose to use it in a certain scenario. It's not generally considered bad style as long as it serves a specific purpose and is well documented.
I remember a command that checks that a given condition is true, otherwise it stops the script. It was one word, starting with a, i think starting with att.. and it was just that word, the condition in parentheses, and the semicolon. I've googled everything I can think of and cannot find it!
if(!condition) return; //for a single assertion statement
Furthermore, you might mean "assert." Google it with javascript for a couple of reads on the subject.
You are looking for a function with the semantics of assert(condition), i.e., throw an exception if condition is false. javascript does not contain a native assert like function, but you could certainly implement it yourself. A bit of searching will yield some good results.
function assert(condition) {
condition || throw "assert failed"
}
You can spruce it up a bit as needed, but that's the basic idea.
I don't know if there's something built in natively to JavaScript but have you tried looking at this?
http://aymanh.com/9-javascript-tips-you-may-not-know#assertion
One of my friends is teaching a programming class with Javascript and one of his assignments was to create a number guessing game. This was his example implementation:
funProgram: for(;;) {
numberGuesser: {
var num = (Math.random() * 100) | 0;
var guess = +prompt("I'm thinking of a number between 0 and 100. Try to guess it.", 0);
var guesses = 1;
guess: for(;;) {
higher: {
lower: {
if(guess === num) break guess;
if(guess > num) break lower;
guess = +prompt("Too low. Try again.", 0);
break higher;
}
guess = +prompt("Too high. Try again.", 0);
}
guesses++;
}
alert("You got it in " + guesses + " guesses! The number is " + num);
}
var again = prompt("Do you want to guess again (y/n)?", "y") === "y";
if(!again) break funProgram;
}
He told me that it's a good practice to label your code and wrap blocks around it so you can easily see what each section is doing. He also said labeled breaks and continues are much easier to read than unlabeled ones because you can know exactly what you are breaking out of. I've never seen any code patterns like this, so I'm not sure if this is true.
I've been using Javascript for a while and there are a few things in here that I've never seen before and some things that I still don't understand. I thought that the break keyword was specifically meant for breaking out of loops. The higher and lower blocks are not loops, but apparently you can still break out of it. How is that possible? It seems odd to me to break out of something that doesn't loop. Can you also break out of functions using the break keyword?
Breaks can in fact have labels (and do so accept them). However, I'm not sure who "He" is, but I would go as far as to say "He" is conveying his ideals of programming, rather than a specific standard. That is to say, there's no need to use labels, it just makes it more legible to that particular person. (And, IMHO, labels are reminiscent of the BASIC/GOTO days which usually results in Spaghetti Code).
Extra Credit: Ask your friend if they used to write in BASIC; I'm betting you'll get a "yes" (along with a lot of bad habits for the duration of the course--that's not to profile, I've just never had a good experience with BASIC/VB programmers following [current] coding patterns))
The break command is commonly used to exit loops, however if the code block is nested within a label, you're establishing yet another block which you can break from. It also gives you a bit more flexibility as to where the break is meant to exit from. For example:
for (;;){ // "for a"
for(;;){ // "for b"
break; // breaks "for b"
}
}
In this instance, break is only meant to exit the nested ("for b") loop. However:
myblock: {
for(;;){
for(;;){
break mybock; // breaks label "myblock"
}
}
}
In this case, break is actually exiting both loops because you're instructing it to quit the label block entirely. This would be almost like having:
function myblock(){
for(;;){
for(;;){
return; // exits function "myblock"
}
}
}
Where return exits the block similar to the way break myblock acts.
By the way, not for nothing, I find this a tad easier to read:
var again = true;
while (again){
var num = (new Date()).getMilliseconds() % 100,
guess = +prompt("I'm thinking of a number between 0 and 100. Try to guess it.", "1"),
guesses = 1;
while (num !== guess){
guesses++;
guess = +prompt((guess < num ? "Too low." : "Too high.") + " Try again.", guess);
}
alert("You got it in " + guesses + " guesses! The number is " + num);
again = prompt("Do you want to guess again? (y/n)", "y") == "y";
}
I can understand the code after a little research on label and break in javascript. However, I personally don't like that style of coding, mainly because the labelled block syntax is too similar to the literal object notation - which I use a lot. And even Mozilla's documentation on labels tell us to avoid them:
Labels are not very commonly used in JavaScript since they make programs harder to read an understand. As much as possible, avoid using labels and, depending on the cases, prefer calling functions or throwing an error.
Regarding your objective questions:
break can be used to exit for loops, while loops and case statements, as well as labelled blocks.
You cannot use break to exit a function, you must use return.
From MDN (bold emphasis mine):
The break statement includes an optional label that allows the program
to break out of a labeled statement. The break statement needs to be
nested within this labelled statement. The labelled statement can be
any block statement; it does not have to be preceded by a loop
statement.
So, yes, labels can be used outside of loops, but, no, you can't use them to return from a function.
Those break statements are being used in the same way that goto is used in older languages. And as Shark pointed out: you can also use them in switch statements, but not in functions.
It's probably confusing to you because he is using the labeled blocks in conjunction with infinite for(;;) loops.
Look at this article here for more information: http://james.padolsey.com/javascript/labelled-blocks-useful/
Why JSLint report in code:
function cos(a) {
var b = 0;
if (a) {
b = 1;
}
else {
b = 2;
}
return b;
}
error:
Problem at line 6 character 5: Expected exactly one space between '}' and 'else'.
This error can be turned off by disabling Tolerate messy white space option of JSLint.
Or in other words -- why syntax:
} else { is better then
...
}
else {
...
Google also uses syntax with } else { form.
But I don't understand why. Google mentioned ''implicit semicolon insertion'', but in context of opening {, not closing one.
Can Javascript insert semicolon after closing } of if block even if next token is else instruction?
Sorry that my question is a bit chaotic -- I tried to think loud.
JSLint is based on Crockford's preferences (which I share in this case).
It's a matter of opinion which is "better".
(Although clearly his opinion is right ;)
It's not a matter of style. It's how ECMAScript works.
For better or for worse, it will automatically insert semicolons at the end of statements where it feels necessary.
JavaScript would interpret this:
function someFunc {
return
{
something: 'My Value'
};
}
As this:
function someFunc {
return;
{
something: 'My Value'
};
}
Which is certainly what you don't want.
If you always put the bracket on the same line as the if and if else statement, you won't run into a problem like this.
As with any coding language, the coding style chosen should be the one that minimizes potential risk the most.
Mozilla Developer Network also promotes same line bracketing: https://developer.mozilla.org/en-US/docs/User:GavinSharp_JS_Style_Guidelines#Brackets
JSLint is being very picky here, just enforcing a style that you might not share.
Try JSHint instead:
The project originally started as an effort to make a more configurable version of JSLint—the one that doesn't enforce one particular coding style on its users [...]
JSLint is just being picky here. The guy who wrote it also baked in many stylistic suggestions in order to keep his own code more consistent.
As for semicolon insertion, you shouldn't need to worry here. Inserting a semicolon before the else clause would lead to a syntax error and automatic semicolon insertion only occurs in situations where the resulting code would still be syntactically valid.
If you want to read more on semicolon insertion, I recommend this nice reference
Basically if you insert semicolons everywhere you only need be careful about putting the argument to "return" or "throw" (or the label for "break" and "continue") on the same line.
And when you accidentally forget a semicolon, the only common cases that are likely to bite you are if you start the next line with an array literal (it might parsed as the subscript operator) or a parenthsised expression (it might be parsed as a function call)
Conclusion
Should you omit optional semicolons or not? The answer is a matter of
personal preference, but should be made on the basis of informed
choice rather than nebulous fears of unknown syntactical traps or
nonexistent browser bugs. If you remember the rules given here, you
are equipped to make your own choices, and to read any JavaScript
easily.
If you choose to omit semicolons where possible, my advice is to
insert them immediately before the opening parenthesis or square
bracket in any statement that begins with one of those tokens, or any
which begins with one of the arithmetic operator tokens "/", "+", or
"-" if you should happen to write such a statement.
Whether you omit semicolons or not, you must remember the restricted
productions (return, break, continue, throw, and the postfix increment
and decrement operators), and you should feel free to use linebreaks
everywhere else to improve the readability of your code.
By the way, I personally think that the } else { version is prettier. Stop insisting in your evil ways and joins us on the light side of the force :P
I have just finished reading a book titled Mastering JavaScript High Performance. I speak under correction here, but from what I can gather is that "white space" does in fact matter.
It has to do with the way the interpreter fetches the next function. By keeping white space to a minimum (i.e.) using a minifier when your code is ready for deployment, you actually speed up the process.
If the interpreter has to search through the white space to find the next statement this takes time. Perhaps you want to test this with a piece of code that runs a loop say 10,000 times with white space in it and then the same code minified.
The statement to put before the start of the loop would be console.time and finally console.timeEnd at the end of the loop. This will then tell you how many milliseconds the loop took to compute.
The JSLint error/warning is suggesting to alter code to
// naming convention winner? it's subjective
} else if{
b = 2;
}
from:
}
else if{
b = 2;
}
It prevents insert semicolons; considered more standard & conventional.
most people could agree a tab between the
}tabelse if{
is not the most popular method. Interesting how the opening bracket { is placed (space or not) obviously both ar subjected