What is the role of variables (var) in Javascript - javascript

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.

Related

Whats up with eval()?

I've seen a lot about how the eval() function is evil; not a wise choice for HTML/JavaScript programming. I would like to use a function where I can pass in a string to have it read as a variable name, and eval() seems to do just that, but I don't want to use a destructive function.
From what I understand, the issue with eval() is that it can read third-party input as actual code, which opens a door for malicious activity. I have a map element that keeps track of location using strings for the location names. I also have large blocks of text assigned to variables so I can pull up a description of the current location easily. This seems like an acceptable time to use eval, as the strings that I would be passing in would be provided by other parts of the code. Is this a fair judgement, or is there some other function that I should be using?
(Moving my comment as an answer)
An easy way to get around that is to save whatever variable you're interested in accessing in a javascript Object (i.e. key-value pairs), and access them via indexing. This simple use case doesn't need eval.
From what I understand, the issue with eval() is that it can read third-party input as actual code, which opens a door for malicious activity.
This is not the only reason. One could argue that by today's standards the performance of JavaScript code is negligible.
However, one has to take into account that eval() actually invokes the JavaScript interpreter which is significantly slower than writing the code upfront. ยน
I would like to use a function where I can pass in a string to have it read as a variable name, and eval() seems to do just that, but I don't want to use a destructive function.
This does not warrant the use of eval(). As mentioned in the comments, you can achieve this with keeping track of variables in an object:
let vars = {}
vars["some_variable_name"] = "test"
const var_name = "some_variable_name"
console.log(vars[var_name]) // "test"
as the strings that I would be passing in would be provided by other parts of the code
Might be, but what if in the future some piece of that code actually does process some user input?
Not worth the performance penality and obvious security risk in my opinion.
For a simple way to use a variable name as a string is to use an Object (called a dictionary or map in some languages)
const stringToGrade = {
"freshman": 9,
"sophomore": 10,
"junior": 11,
"senior": 12,
};
document.querySelector("#btn").addEventListener("click", () => {
const asString = document.querySelector("#inp").value.toLowerCase();
const grade = stringToGrade[asString];
console.log(`Your grade number is ${grade}`);
});
<input id="inp" placeholder="Enter your grade level (freshman, sophomore, etc.)" />
<button id="btn">Submit</button>

Create a unique function name on the fly for shared timer

I'll start with the exact nature of the problem and then give some background. I am trying to name a function -threadTimer- and give it a random unique identifier, such as 'threadTimer'+ID. A randomly generated ID would work fine. Then, I need to use setInterval on it, to make it fire repeatedly and therein lies my coding problem. I have tried every variation of new, function, function as an object and I just can't get my head around it. You'll notice that the function I have created is an object and perhaps this is where I'm going in circles.
OK, the background I mentioned. threadTimer is fired by a master timer co-ordinating several threads. That's why you'll see I have generated a 'global' object for reference elsewhere. similar HTML entities can fire threadTimer at the same time, hence my requirement to make each instance unique.
window['GlblThreadExe'+ID]=setInterval(function(){threadTimer(elid,parent,lft,top,diameter,point,bStyle,color,grp,startTime,size,ID,counter,div,divwth,divht,wthIncrement,htIncrement,lftStart,topStart,lftIncrement,topIncrement)},interval);
function threadTimer(elid,parent,lft,top,diameter,point,bStyle,color,grp,startTime,size,ID,counter,div,divwth,divht,wthIncrement,htIncrement,lftStart,topStart,lftIncrement,topIncrement){
// more code
}
In truth, I think its the volume of parameters that I'm passing that's confusing my syntax. Any help appreciated
Avoid polluting window
Generally instead of polluting the global namespace you can store your setInterval ids in some variable
let intervalIds = {}
intervalIds['GlblThreadExe'+ID] = setInterval(function()...)
If really necessary, then store intervalIds to window
window.intervalIds = intervalIds;
Wrap your anonymous function
When you create the "clock", do not call setInterval directly:
Here, createTimerWithId will return a function which calls threadTimer
Dirty id generation
Use a timestamp, and mix it with some random stuff. Or better use a UUID
setInterval(createTimerWithId(), 1000)
function createTimerWithId(){
let id = Date.now()+Math.random(); //no lib, oneliner. good enough to debug
return function(){//the same function you gave to setInterval in your example
threadTimer(id, ...)
}
}
We can do better
In 1. we generated an id on the fly and thus
your code is not testable (id will always change(well except if you mock Math and Date...)).
your id is ugly (a float...)
it will be hard to know from which setInterval you come from
instead, give it the ID.
function createTimerWithId(ID){
return function(){//the same function you gave to setInterval in your example
threadTimer(ID, ...)
}
}
window['..'+ID] = setInterval(createTimerWithId(ID));
shorter version being
window['..'+ID] = setInterval((id=>{
return function(){
threadTimer(id, ...)
}
})(ID),1000);

casting variables at time of use or at time of declaration

sInternal debate at work on best practice, I'm hoping some experienced people can chime in with "WHY", not just "you should...".
is there a functional difference between casting a variable (a) only when it is initialized or (b) when it is initialized AND every time you used it.
A.
var a = 1;
var b = 1;
... potential other code ...
var c = a + b;
var msg = '';
... potential other code ...
echo msg;
vs.
B.
var a = 1;
var b = 1;
... potential other code ...
var c = int( a ) + int( b );
var msg = '';
... potential other code ...
echo trim( msg );
A co-worker doesn't like all the 'extra' function calls to clutter his code and he claims there is an overhead that is not needed - unless you are dealing with user input, and even then you only need to 'cast' or operate once, when you put the user input into a var.
I take the opposite position of wanting to 'cast' every time I use the variable, especially before it goes into a data store, but I've become a proponent of even doing this type of operation when I'm displaying or using a var in any way. The only time I've had this bite me is when doing long floating point math (depending on how the cast operates).
I guess my though is that if I'm expecting a numeric value, or; in the above example, an integer. That casting on initialization works fine, but before I use the variable at any point, I want to use the type I'm expecting. So casting at the time of use seems prudent. This is especially true in loosely typed languages.
Can I get some thoughts on this? thank you
There's no real sense to do it. If it's int then it's int until it changes.
Yes, you need to always check the info coming from user. But there's no real need to clutter your code and make the work on it so inconvenient. To work with, to read this code would be just hell. And also you add some load on the browser's interpreter, making scripts larger and working slower.

Scenarios for Re-using Variables within the Same JavaScript Function: Always a No No?

I've just finished writing a script for parsing csv data. Having recently installed JShint, it's been badgering me about the re-use of variables. I've been using JS a fair bit lately, but I come from a python background where it's normal to reuse variables. I'm wondering what issues there are with reusing variables in the following two examples:
Loop with a Switch
The following loop steps through the rows on a csv file, and when it passes a certain value in a row, it switches variable "currentSwitch" from false to true. After currentSwitch is tripped, the loop starts to push stuff to an array.
for (f=0; f < data.length; f++){
if (data[f][0] === code){
if (currentSwitch === true){
dataListByCode.push(data[f]);
}
}
else if ((data[f][0]).slice(0,4) === "UNIN"){
var currentSwitch = true;
}
}
Processing Data with Broken Out Functions
I've got a few functions for processing data that it makes sense to keep separate. In the following code, I process with one function, then I process with another.
var dataListByCode = addDivideData(dataListByCode);
var dataListByCode = addBeforeEntriesArray(dataListByCode, invNumber, matterNumber, client, workType);
Can anyone tell me if this is not in line with best practice? Is there anything that could go wrong with either of these (or scenarios like them)?
You don't need to redeclare currentSwtich
var currentSwitch = true;
In fact it really doesn't make any sense to redeclare this variable in the middle of the loop and in most cases it's almost certainly not what you actually want.
Just initialize/declare it once at the beginning of your loop
var currentSwtich;
// or
var currentSwitch = false;
and drop the var when you set it to true:
currentSwitch = true;
Basically what you are doing is creating a brand new variable with the same name as the old one, and throwing away the old one. This isn't really what you want normally.
There is no analogous concept in python because python doesn't require you to declare variables.
The major problem with reusing variables is that:
a.) in bigger code blocks it can get very confusing, especially if you added/removed code ~20 times, and kept reusing same ~5 variables for multiple things
b.) any programmer that knows nothing about code(read: you after couple months/years) will have a much more difficult time grasping the code.
The lower function snippet can be expressed as:
var dataListByCode = addBeforeEntriesArray(addDivideData(dataListByCode), invNumber, matterNumber, client, workType);
which is not that problematic. The breaking up of functions is useless in this case, and if you have many inline function chains that is usually sign that you need to rethink the object/function design.

Is it possible to concatenate a function input to text of another function call?

Firstly appologies for the poor title, not sure how to explain this in one line.
I have this Javascript function (stripped down for the purpose of the question)...
function change_col(zone){
var objects= zone1227.getObjects();
}
I am passing in an integer into the function. Where I have "zone1227", I want that 1227 to be the integer I pass in.
I've tried this;
var zonename = "zone" + zone;
var objects= zonename.getObjects();
but that doesn't work.
Is this possible? The functions do exist for every possible integer passed in, but I was hoping to keep the code compact rather than a long list of if statements with hardcoded function names.
Since zone1227 is apparently a global variable, it can also be written as window.zone1227 or as window['zone1227']. This means that you can achieve what you describe, by writing this:
function change_col(zone){
var objects= window['zone' + zone].getObjects();
}
Nonetheless, I agree with Interrobang's comment above. This is not a good way to accomplish whatever it is that you really want to accomplish. You should not be referring to global variables via strings containing their names.
No, you cannot refer to a variable with the value of a string, nor can you concatenate anything onto a variable name. EDIT: turns out you can. You still shouldn't.
Yes, you can avoid using a long hard-coded if/elseif sequence: use an array.
Then you can say this:
function change_col(arr, i)
{
var objects= arr[i].getObjects();
}
And the call would be something like:
change_col(zone, 1227);

Categories

Resources