Not writing "var" before new variable in JavaScript - javascript

I am just learning JavaScript, and I don't understand why the following code doesn't produce an error:
myTest = 5;
function addFifteen(num) {
return num+15;
}
document.write(addFifteen(myTest));
Why do I not need "var" before "myTest"? If it runs without "var", what is the purpose of writing that?

When you do not specify a var before the variable, it is still valid javascript. This is why it does not produce an error. However, as a best practice, you should avoid this, because variables thus declared get tagged to the global scope window.
Having too many variables / functions thus declared is said to "pollute" your global scope and isn't considered good programming practice.
There is a more thorough explanation about this on MDN

Related

Why is var not deprecated?

Lately after ES6 released, many sources suggested that I use "const" and "let" instead of "var", and that I should stop using "var" in my JavaScript.
What I wonder is, if "var" has no advantage over "let" in all points of view, then why didn't they just fix var, or even deprecate "var" instead of letting them go along side each other?
Backwards compatibility.
You're right in saying there is no real advantage to using var over let - if you define them at the start of a function their meaning is basically identical.
You're right that there is no real reason to write new code using var (except maybe this, if relevant).
There are pages on the internet that are decades old though, and no one is going to rewrite them. There is nothing really to gain by removing var from the language. For languages like HTML and Javascript that are interpreted - backward compatability is absolutely mandatory.
That is also why they chose not to simply redefine var. Take the following example code;
// THIS IS AN EXAMPLE OF BAD CODE. DO NOT COPY AND PASTE THIS.
if (logic) {
var output = "true"
} else {
var output = "false"
}
console.log(output)
If var was changed to behave like let then the console.log would cause a reference error because of the scope difference.
I believe sometimes you need to redeclare a variable to write less code.
One example is this function that generates a unique id:
function makeUniqueId(takenIds) {
do {
var id = Number.parseInt(Math.random() * 10);
} while (takenIds.includes(id))
}
Which may be invoked like that
makeUniqueId([1,2,3,4,5,6,7])
Here I declare id variable simply inside do block and it get's "hoisted" to the function scope. That would cause an error if I used let, because while block wouldn't see the variable from the do block. Of course I could declate let before do..while, but that would create the same function scoped variable with extra line of code.
Another example is when you copypaste code to devtools console and every time variables get redeclared.
One more example. What if you want to keep your variable declarations close to their usages but still treat them as function globals? If you use let in this fashion, you'll get rather confusing expirience in dev tools (all those Block, Block scopes).
But var 'keeps' them together in one 'Local' list:
Everything has their own advantages and disadvantages using var const and let is dependent on their use cases.
var
Variable declarations are processed before the execution of the code.
The scope of a JavaScript variable declared with var is its current execution context.
The scope of a JavaScript variable declared outside the function is global.
let
The let statement allows you to create a variable with the scope limited to the block on which it is used.
const
const statement values can be assigned once and they cannot be reassigned. The scope of const statement works similar to let statements.
I hope you understand.

Tune My Javascript

I have a JavaScript global Array, which I'm using in multiple functions. I heard that using global variables will give some performance headache. So, can anyone suggest me how I can avoid using global variable in this case?
var tpaArray = new Array();
In multiple functions, I am using and popping value from it.
[Note] In my code I am actually using multiple global variable and arrays
Global variables are not a performance problem. The problem with globals is that the global namespace is already very, very crowded, and so dumping your symbols there leads to the possibility of conflicting with something else.
It's almost always possible to avoid having globals. The usual way is to wrap all of your code in a scoping function:
(function() {
// Your code here
})();
Then you can have nested functions inside that function, and "globals" within that function that they all share.
(function() {
var someVar;
function foo() {
// You can use `someVar` here
}
function bar() {
// And also here
}
foo();
})();
That said, it's best to avoid having lots of shared variables or near globals, as it makes for writing functions with side-effects, which can be difficult to maintain.
If you have lots of variables, you can put them all into an object and pass this as an argument to each function. Then instead of accessing tpaArray, you'd access data.tpaArray, where data is the name of the argument.

Reaching a variable from nested function in Javascript

Can somebody please explain me why the following code works?
function getLastName()
{
fullName.lastName = "World";
}
function writeName()
{
fullName = {};
fullName.firstName = "Hello";
getLastName();
document.write(fullName.firstName + " " + fullName.lastName);
}
writeName();
For some reason, getLastName() can reach local its enclosing method's local state. How can this work? And also should I utilize this feature of Javascript or it is considered as a bad practice? If it is a bad practice, could you please explain why?
You can see the actual code working here at http://jsbin.com/atituk/2/edit
You don't have any local variables, that would require using the var keyword. All your variables are global and can be accessed anywhere within window, which is not considered good practice at all.
You have not used the var keyword against fullName inside the writeName function, you are therefore taking it from the scope outside writeName. It continues up the chain until it reaches the outer most scope, at which point it creates a global.
Globals are, in general, bad practise as they are hard to keep track of and more likely to be overwritten by accident (e.g. in a race condition).
If you were using strict mode this would create an error instead of a global.
You are using all variables of yours as global variables. So all are recognized everywhere. In order to have a better understanding of variable scopes in Javascript have a look at this great example https://stackoverflow.com/a/500459/655316

Prevent 'global' references in javascript

I've got a problem of having code variable names conflicting each other, ie;
<script type="text/javascript">var a = "hello"; </script>
<script type="text/javascript">alert(a);//this works, when I want 'a' not to exist </script>
Are closures the only option?
Coming from a c# background, its like constructing an unreferenced instance of a delegate, then calling it inline, which seems a bit messy
(function(){var a = "hello";})();
(function(){alert(a);})();//yes! working as expected
Using a (immediately self-executing) function to create a new scope is indeed the way to go.
This also has the advantage that you can ensure that certain variables have certain values. When using jQuery, the following is common for example:
(function($, window, undefined) {
// ...
})(jQuery, this);
Unless you have tons of functions with only a single statement in each (like in your example) it is also perfectly readable.
Yes, closures are your only option. In browsers all JavaScript files get put into the same global scope.
IIFE's are very common place in JavaScript; I wouldnt' call them messy.
Javascript only has function scope, unlike C# which has block scope. The following code is valid javascript and C#:
var x = 2;
while(true) {
var y = 3;
break;
}
//y is not accessible here in C#, but is in javascript
The only way to create a new scope is to create and execute an anonymous function.
For short, inline stuff then you're best to use the module pattern to create a closure and therefore emulate private variables.
(function(){
var a....
})();
A better long-term approach is to use objects as namespaces.
var NS = {};
NS.a = 1;
Just to provide a different perspective. It is possible to write code without using closures, and maintain (arguably) safe global variable scope.
Define a single object, to use as a namespace, with a suitably unique name (e.g. MyAppContext) that will have global scope, and if you need to define global-like variables only for use in your application only, attach them to this object.
MyAppContext.appTitle = 'Application Title';
At the start of your script where you create MyAppContect make sure it doesn't aleady exist.
Make sure that all of your function-scoped variables use the var keyword so you know you're not referencing a global value.
Obviously this approach opens up a risk that you forget to define some of your function variables with var. JSLint can help you in respoect of this this.
I am happy to retract this answer if I start getting flamed, but I believe it is a workable alternative approach to using closures. And hey! it's old skool
I also agree that the use of closures is safer, but thought this might interest you.

Distinguishing closure and local variables

A local function in the closure declares a variable with the same name which exists in the closure. So, how could we access closure's variable from the local function?
function closure()
{
var xVar;
function func1()
{
var xVar;
// how to distinguish local and closure scopes.
return xVar;
}
return function () { return func1(); };
}
Creating a private object and making private variables as properties of this object could help. But I am wondering if there is a better and neat solution. Can a scope chain help?
I have edited to make it a complete closure. Anyway, closures are not much concern here, it could be considered for inner functions however, there may be a solution with closures somehow.
Thanks
You can't access the scope chain explicitly in JS. Your problem is the age-old one of variable shadowing, but it's that much more maddening because in JS, the scope chain is actually there at runtime, it's just not available for you to access.
You can play some tricks with rejiggering current scope if you use the hated with operator, but that (as well as arguments's caller/callee stuff) really just give you access to objects and functions with their properties. There's no way to say "give me what xVar means in the n-1 runtime scope from right here".
Variables defined in an inner scope hide variable declarations in an outer scope. The "better and neat solution" is not to reuse variable names that way.
In your example the xVar variable is not a closure, because you redefined its scope to each function. To use that variable as a closure continue to declare it with the var command in the closure() function and then do not declare it with the var function in the func1() function. Instead just use the variable immediately in func1().
There is not an easy way to test if a function is a closure or a local variable. You would have to perform some sort of flow control test and then analyze assignments, where assignments occur, and where assignments do not occur. Then you must compare those results. You could write a tool, in JavaScript, to perform that analysis upon a given input and write you a report as output.

Categories

Resources