This isn't the exact use scenario but I was wondering if it was possible to get the value passed to the switch statement without having to retype what is in the switch() part.
Example :
switch(someObject.withSomevalue*(Math.random()*11)) {
case 1 : alert("one");
// more cases here
default: alert(theNumberThatWasPassed);
}
If we run the Math.random() again we'll get another random number that very well could meet one of the cases, so calling what aws called in the switch(x) statement isn't an option. I've been just storing it in a variable - x = someObject.withSomevalue*(Math.random()*11) - and then passing it to the switch that way switch(x), but I was wondering if it's possible to get the value passed to the switch within the switch statement.
As everyone else pointed out you have to save it in a variable. But you can do the following in the expression though I do not know how cross browser compatible this is:
switch(x = <your expression>){
//
default:alert(x);
}
and at least you save one line of code.
This is the same as asking if you can find the values for if(Math.random()){...}. The answer is no, because they are language constructs, and not functions.
Just capture it into a variable before the switch and use that variable.
var myValue = someObject.withSomevalue*(Math.random()*11);
switch(myValue) {
case 1 : alert("one");
// more cases here
default: alert(myValue);
}
I would say your best bet would be to do what you currently are doing, and capture it into the variable before the switch statement. Is there any reason you would not want to do this besides saving a line of code?
Interesting... OP, I'm trying to look at your thought process. Maybe just write out the code how you think it should look like (ignoring that it wouldn't work in the first place).
update:
At least in C/C++, you can just form another block to have the var only be accessible within the switch:
...
{
var mySwitchVar = blah;
switch(mySwitchVar) {
case blah blah blah:
default blah blah:
}
}
...
Related
I am currently learning JavaScript and I am wondering what is the role of the variables (var).
In the example bellow, on the last two lines we first define a variable "monCompte" in which we call "john.demandeCaissier(1234)". Then we use console.log(monCompte) to print the result on the screen. What I don't understand is why do we first need to define the variable "monCompte" to call "john.demandeCaissier(1234)". Why can't we just do something such as:
console.log(john.demandeCaissier(1234));
Example
function Personne(prenom,nom,age) {
this.prenom = prenom;
this.nom = nom;
this.age = age;
var compteEnBanque = 7500;
this.demandeCaissier = function(mdp) {
if (mdp == 1234) {
return compteEnBanque;
}
else {
return "Mot de passe faux.";
}
};
}
var john = new Personne('John','Smith',30);
var monCompte = john.demandeCaissier(1234);
console.log(monCompte);
Thank you for you answers.
Yes, you can inline your function call and avoid the need for a variable. However, if an error occurs on that line, it becomes harder to debug:
var monCompte = john.demandeCaissier(1234);
console.log(monCompte);
vs
console.log(john.demandeCaissier(1234));
in the second example, there are several different modes of failure that would not be apparent in a debugging session. When split over two lines, some of those failures become easier to track down.
Second, if you wanted to reuse the value returned by john.demandeCaissier(1234) (the author might have shown this), then a variable becomes very useful indeed.
In my opinion, it's a worthy pursuit to perform only a single operation per line. Fluent-style advocates might disagree here, but it really does make debugging considerably easier.
You could definitely do that, but in more complex programs you will need to store variables for several reasons:
Shortening Long Expressions
Imagine if you saw this code somewhere:
console.log((parseInt(parseFloat(lev_c + end_lev_c)) - parseInt(parseFloat(lev_c + start_lev_c)) + 1));
BTW I got that from here
Wouldn't it be so much simpler just to split that expression up into different variables?
Storing Data
Let's say that you take some input from the user. How would you refer to it later? You cannot use a literal value because you don't know what the user entered, so do you just call the input function again? No, because then it would take the input a second time. What you do is you store the input from the user in a variable and refer to it later on in the code. That way, you can retrieve the value at any time in the program.
If you are a beginner, you might not see any use for variables, but when you start writing larger programs you will start to use variables literally in almost every line of code.
Variables exist to store data. They're useful because instead of invoking an operation over and over again, which is criminally inefficient, they allow you to invoke an operation once, and then use that result where necessary.
And that's for all languages, not just JavaScript.
Variables are structures that store some value (or values). They're only that and you could probably do all your code (or the majority of it) without them.
They help you organize and add some readability to your code. Example:
alert(sumNumbers(askNumber()+askNumber()));
takes a lot more effort to read/understand then this:
var firstNumber = askNumber();
var secondNumber = askNumber();
var total = sumNumbers(firstNumber + secondNumber);
alert(total);
Sure it's longer but it's more readable. Of course you don't have to use var for everything, in this case I could just hide the total.
Another common use for variables is "caching" a value.
If you had a function that sums like 1 million values, if you keep calling it for everything, your code would always have to do all that hard work.
On the other hand, if you store it on a variable the first time you call it, every other time you need that value again, you could just use the variable, since its a "copy" of that calculation and the result is already there.
I have an issue with JavaScript case sensitivity and I will need your valuable piece of advice here. I have the following object created:
var foo = function () {
this.myColor1 = '#000000';
this.MyColor2 = '#FF2000';
this.MyCOLOR3 = '#FFFFFF';
}
as you can see, each property may come in any case form, lowercase, uppcase, mixed, etc. These values are coming from a database and I don't have control onto them.
I want to be able to call them ignoring the case sensitivity. For example, I would like to be able to call them like this:
console.log(foo.mycolor1);
// or
console.log(foo.myColor1);
I guess my only approach to achieve this, would be to convert everything in, let's say, lowercase when I define those, and then, when I call them back to convert my request into lowercase again.
A little piece of background here; my aim is to provide an SDK to a few developers that they will write their own code for a platform I am working on. These values will be saved by the developers themselves into a database. For some reason, all those values are stored in lowercase. So, I either have to tell them 'no matter how you set them, you should request everything in lowercase', or, ideally, I should find a way to convert everything before their request is post.
An idea would be to write a method, and tell them to make the request like this
foo('mycolor1');
foo, is going to be a function that would handle the case sensitivity easily. But, I would prefer to use the foo.mycolor1 notation, so ... your help is needed :)
FYI, jQuery is available!
Thank you,
Giorgoc
when you render the javascript from DB use toLower() to set the variables names... and then reference them in lower case...
I am converting tutorials for students (2nd language speakers, 9 to 12 yrs old) to access in an offline / intranet context. Hence the websites I would like them to use are unavailable.
I am trying to mimic the 'alter the code' style of tutorials for helping with JavaScript / HTML5 Canvas.
This works :
<canvas id="myCanvas" height="400px" width="400px"></canvas>
<script>
function update(){
eval(document.getElementById('demoScript').value);
}
var ctx = document.getElementById("myCanvas").getContext("2d");
</script>
<textarea id="demoScript">
ctx.fillRect(100,100,50,50);
</textarea>
<input type="button" value="update" onClick="update()">
... but everything I have read says eval() is a bad idea.
I can get the textarea content to pop-up in a div if I want, but I can't get it to pop-up in a script anywhere ... leaving me with just eval().
Options and recommendations for alternatives please ... or this is as good as it gets ?
This is an acceptable use for eval, because at worst a student will lock up their own browser with an infinite loop.
First of all, it's not a "bad idea" to use eval.
Second: anything that replaces eval will have the same "disadvantages" since it executes code. You'll have to execute code to do this. If you don't want to make your own interpreter (which is at least ten times worse and more vulnerable) you'll have to stick with eval or something similar.
Now what is the danger of it? Nothing else but the fact that it executes code. It's like telling someone that a hammer is dangerous because it hits hard - YES, and it's necessary when it gets to nailing something. Of course, a hammer can kill.
So,
Use eval,
...but sanitize the code it gets (= watch out for dangerous expressions, etc).
You can limit a lot of things for the user, like only one instruction per line, only double quotes, etc, to make it more controllable. Anything that's off the limit will be deleted. If no dangerous thing can be pushed thru the input, eval is harmless.
Options and recommendations for alternatives please ... or this is as good as it gets ?
I'd suggest using the Function constructor instead of eval. While in your simple example it may not make much difference, in other cases it may.
This will make the code evaluate in the global scope, so none of your local variables can be touched. It also allows JS engines to more easily optimize the local code. Using eval() can disable optimizations.
So to use the Function constructor, just pass the code to eval as the last argument. Since you have no parameters to define for the new function, it'll be the only argument.
var f = new Function("return " + document.getElementById("demoScript").value);
Then invoke the function.
f();
Notice that I concatenated a return statement into the provided code. This isn't required if you don't care about getting the returned value from the code your invoking, and should be removed if it might interfere with the provided code.
And of course, you can do this all in one line if you're only going to invoke it once.
new Function(document.getElementById("demoScript").value)();
You can get the value string from the textarea, split, validate and run it manually.
For a demonstration like this, where ctx is given, something like this should work
var ctx = document.getElementById("myCanvas").getContext("2d");
function update(){
var val = document.getElementById('demoScript').value,
fn = val.match(/\.(.*?)\(/),
arg = val.match(/\((.*?)\)/);
if (fn && fn.length > 0) {
if (arg && arg.length > 0) {
var args = arg[1].indexOf(',') != -1 ? arg[1].split(',') : [arg[1]];
ctx[fn[1]].apply(ctx, args);
}else{
ctx[fn[1]]();
}
}
}
FIDDLE
You could do
var fn = document.getElementById("demoScript").value;
window[fn]();
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.
function demoMatchClick() {
var validString = /^[a-z](?=[a-z]*[0-9])[a-z0-9]{0,6}[a-z]$/
var re = new RegExp(validString);
if (document.form1.subject.value.test(re)) {
alert("Successful match");
} else {
alert("No match");
}
}
<INPUT TYPE=SUBMIT VALUE="Replace" ONCLICK="demoReplaceClick()">
I can't get it to popup an Alert to pop up
I want these rules to be enforced
•Not have upper-case letters.
•Begin with a letter.
•Have at least 1 digit(s) not at the beginning and end.
•Have up to 8 alphanumeric
•Does NOT have any symbols like ##$ characters (symbols like !##$%^&*()-+).
I am using a button to execute the code for now.
Well, I suppose this regex suits your rules...
var rules = /^[a-z](?=[a-z]*[0-9])[a-z0-9]{0,6}[a-z]$/;
But I think there are several issues with your code, which I'd like to point out. Don't take it as a personal offense, please: believe me, I'm actually saving you a LOT of time and nerves.
First, there's a standard rule: each function should do only one thing - but do it really well (or so they say, these perfectionists!). Your code is too tightly coupled with DOM extraction: I was really surprised when it failed to work when pasted in my environment! Only then I noticed that document.forms call. It's not really needed here: it's sufficient to build a function taking one parameter, then call this function with the value extracted somewhere else. This way, btw, you can easily separate the causes of errors: it would be either in DOM part, or within the function.
Second, Regexes are really very close to be considered first-class citizens in JavaScript (not so as in Perl, but still much closer than in some other languages). That means you can write the regex literals as is, and use it later - without new Regexp constructs.
With all that said, I'd write your code as...
function validatePassword(password) {
var rules = /^[a-z](?=[a-z]*[0-9])[a-z0-9]{0,6}[a-z]$/;
return rules.test(password);
}
... then use it by something like ...
var password = document.form1.subject.value;
alert( validatePassword(password) ? 'Success! :)' : 'Failure... :(' );
P.S. And yes, Riccardo is right: set too strict rules for passwords - and suffer the consequences of narrowing the range of search for an attacker. And it's quite easy to see the validation rules set in Javascript: even obfuscators won't help much.
Here is the modified code:
function demoMatchClick(input) {
var validString = /^[a-z](?=[a-z]*[0-9])[a-z0-9]{0,6}[a-z]$/;
if (validString.test(input)) {
alert("Successful match");
} else {
alert("No match");
}
}
demoMatchClick("hello world");
validString variable is already a RegExp object and you can use it directly, additionally .test() method belongs to regex object not to string.