Is there any difference between defining and declaring variables in javascript? - javascript

It may seem very trivial issue but very confusing and recurring for me. In some manuals for javascript or tutorials these terms are used alternately.
In others I found the explanation that we declare variables when we create them with var const let and we define variables, when we append some value/object to the declared variable as below:
var name; //declaring
name = 'Adam' //defining
var age = 'dead' //declaring + defining
Are there any approved and correct rules of using these two terms?

I'd say that "variable definition" is not a standard JavaScript term.
Functions (of all kinds) and object properties can get defined, but variables always get declared. This terminology might hint at the declarative nature of variables - a declaration always applies to the complete current scope, it's not an action that gets executed and does something.
var name is a declaration. var age = 'dead' is a declaration with an initialiser. name = 'Adam' is just an assignment. I'd guess that "defining" a variable refers to it no longer being undefined, so both an assignment statement or the initialiser of the declaration might do that. I'd rather speak of the initialisation of the variable, though.

var x is a declaration because you are not defining what value it holds but you are declaring its existence and the need for memory allocation.
var x = 1 is both declaration and definition but are separated with x being declared in the beginning while its definition comes at the line specified (variable assignments happen inline).
I see that you already understand the concept of hoisting but for those that don't, Javascript takes every variable and function declaration and brings it to the top (of its corresponding scope) then trickles down assigning them in order.
You seem to know most of this already though. Here's a great resource if you want some advanced, in-depth exploration. Yet I have a feeling you've been there before.
Javascript Garden

Related

Properties vs variables - Javascript

Can anyone tell me the difference between these? I started noticing some behaviours that i was not expecting.
let myObj = {  _name:"Consala",
get name(){
return `Mr. ${this._name}`  }}
Why does this require the this keyword because i thought functions have access to all variables surrounding them.
I explained this by saying that variables are different from properties and there is no variable called _name inside of the myObj just a property. Im not sure if this is correct though.
I tried to test this theory using this:
let test = "banana"
print(test) //prints banana
print(this.test) //prints undefined
this.test = "apple"
print(this.test) //prints apple
I thought this confirmed what i thought because when undefined was printed i explained it as there is no property called test on the global object showing me there is a difference between variables and properties.
But then i changed let to var and then print(this.test) also prints banana instead of undefined...
Whats going on here?
Im pretty confused but im thinking that when you use var you are setting a property to the object its in (which would explain why var has function scope right?) but then what happens when you use let?
**I hope people dont think of this as a low effort post because i have really been trying to figure this one out on my own rather than just refusing to think for myself. Cheers
The reason why var prints banana instead of undefined is because you have declared it outside of all functions so it takes global scope.
The scope of a variable declared with var is its current execution context and closures thereof, which is either the enclosing function and functions declared within it, or, for variables declared outside any function, global.
Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var
On the other hand, let is block scoped so it gives you undefined
And to answer your question about why we need this, it is because the name getter function has no variable called _name in its scope.
Thus it needs this to indicate to it to use the object scope to look for the _name variable
this keyword is the most confusing keyword in JavaScript. It's not because it's kind of buggy or what but it's because developers think it will work in the same way as it does in other languages but that's not true.
this has dynamic scope. Dynamic scoping does not care how the code is written, but instead how it executes. So the value of this depends on how is it executed.
Talking about your first example
let myObj = { _name:"Consala",
get name(){
return `Mr. ${this._name}` }}
In this case, when you call that function you type myObj.name which binds myObj as this to name. So whenever you call a function using [Object Name].[function] you assign this object as the function's this.
Let's come to the second scenario. I assume you tried that in your browser.
In the case of Browser, this refers to window Object (Try console.log(this) ).
What happens there is when you declare a variable using let it doesn't add to Window object but when you declare it using var keyword, it adds to Window Object.
Try declaring a Variable using var and then do console.log(this). You will find that variable in Window Object but in case of a variable declared using let won't be there.

Should we manually hoist all the JavaScript variables to the front of the function definition?

I have heard that since JavaScript would hoist all the local variables to the front of the function, it is better if the programmer just hoist it himself or herself, so that everything is seen as how things would actually occur.
Example is:
var i, result = [];
which is to declare all local variables at the beginning of the function.
But I also saw in some classical code, such as in React JS's source code that it would do
for (var i = 0; i < ...; i++) { ... }
that is, declaring it when i is first used -- so that if this line is removed, the declaration will be removed together.
If we hoist it manually, there is a danger that when that loop is removed, the var i; is still left there. (although linting probably would catch it).
I also have seen weird look from interviewers when I hoists all the variables to the front of the function definition too.
Should we hoist all variables to the front? Or what if we hoist all variables except the temporary variables such as i and j?
Limiting the exposure of variables to the context they are useful in can be an extremely valuable auto-documentation strategy: It lets the next person who picks up the code know where variables are and are not relevant. So no, don't "hoist" because the JavaScript engine is internally doing it
I also have seen weird look from interviewers when I hoists all the variables to the front of the function definition too.
Should we hoist all variables to the front? Or what if we hoist all variables except the temporary variables such as i and j?
There are basically two schools of thought on this. One is to declare all of your variables in one place, usually at the top of whatever they are scoped to (which is the function in which they are defined, if you are using the var keyword). The other school of thought is to declare variables as closely as you can to where they are used. They both have valid arguments, and honestly is a matter of opinion and preference.
Before getting into let and ES6, I will first talk about the two arguments above.
Declaring at the top of the scope
The advantages of this are that you always know where your variable declarations are, and you are always aware of the parent scope. Immediately when looking at the function, you can determine what variables are used throughout, and you can trace where they are used from there.
The disadvantages of this are that, depending on your code structure, it may be 100 lines from where a variable is declared and where it is used, which can make debugging a bit of a challenge sometimes and requires you to carefully trace the variable you think you are using in the function, because it may not always be the one declared at the top, especially in the case of shadowing.
Declaring as close in proximity to where the variables are used
The advantages of this are that when trying to determine variable scoping and shadowing, it is very easy to determine what version of the variable you are working with (especially with nested functions). The other advantage is code-cleanup. If you remove a function or a loop and there is a variable declaration right above it, it is usually a pretty good reminder to remove that variable declaration as well because it will not be needed anymore. Obviously that's not always the case, but many times it is. When declaring at the top, variables can get lost in a sea of declarations and be left unused - yeah a linter can catch that, so it may be a moot point, but it's a point nonetheless.
The disadvantages of this are the exact opposite of the advantages of declaring at the top. If you are looking to see what variable names / identifiers are used in a given scope, you kind of have to go digging. CTRL + F is your friend, but it is faster to look at a list that is all in one place.
Now what about let??
Again, there are two schools of thought on this: one is "let is the new var" and the other is that "let simply allows us to do syntactically what we already were doing stylistically"
For example, take this code:
var result;
for (var i = 1; i <= 10; i++) {
result = 2 * i;
console.log(result);
}
Vs.
for (var i = 1; i <= 10; i++) {
var result = 2 * i;
console.log(result);
}
Now, from the compiler's perspective, they are identical. However, the second version (stylistically) is telling the reader of the code "The result variable is only being used inside this for loop", whereas the first version is ambiguous to the reader as to what may or may not be happening to the result variable later on in the code. These are stylistic and conventions that developers unspokenly adhere to in order to convey intent of the code. And that is the argument of the second school of thought - let simply allows us to do, syntactically, what we are already doing stylistically.
This might have been relevant a few years back.
Now, you should use ES5 or later, which introduced the let keyword, which solves the hoisting issue. let declared variables are block-scoped and will not be hoisted.
I guess sometimes it makes sense to use strict mode
"use strict";
which can be implemented for the whole file or for a function
function strictFunction() {
"use strict";
var y = 3.14; // This is ok
x = 2.414; // This will cause error
}
which can help writing more secure code by avoiding global variables. So technically it depends how your for loop is being use. Reference "use strict";
You can also use let instead or var as suggested by #RemcoGerlich to scope your variables

Why single var is good in javascript?

Can anyone tell me why use one var declaration for multiple variables and declare each variable on a newline consider is a good programming behavior?
// bad
var items = getItems();
var goSportsTeam = true;
var dragonball = 'z';
// good
var items = getItems(),
goSportsTeam = true,
dragonball = 'z';
It is not considered 'good' or 'bad'. It's a matter of preference.
The guy who built the code quality tool JSLint, Douglas Crockford likes it.
One 'advantage' it might have is that it avoids the possibility of variable hoisting. In JavaScript all var declarations move to the top of their scope automatically.
Here is why Crockford thinks the second option is better:
In languages with block scope, it is usually recommended that variables be declared at the site of first use. But because JavaScript does not have block scope, it is wiser to declare all of a function's variables at the top of the function. It is recommended that a single var statement be used per function. This can be declined with the vars option.
It's a preference, I wouldn't say good or bad. Yes JSLint complains about it, I don't really like how it complains about for loop variables being inline as well. The reason that it was put in JSLint was to prevent possible hoisting confusions.
Also in some cases declaring all of your variables at the top will lead to a slightly smaller file. Consider the following:
var a = 10;
a++;
var b = 20;
After Google Closure being run over it
var a=10;a++;var b=20;
As opposed to this if we pull b's declaration to the top.
var a=10,b;a++;b=20;
The main benefit (aside from style preference, I guess) is that it will prevent you from writing code that suffers from unintended variable hoisting consequences.
Take this example:
var foo = function(){alert('foo');}
function bar(){
foo();
var foo = function(){alert('foobar')};
foo();
}
bar();
By reading this code, the intent of bar appears to be as follows:
Call the outer foo function to alert the string 'foo'.
Create a local variable, foo.
Call the local foo function to alert the string 'foobar'.
In reality, what happens is this:
The local variable foo is hoisted to the top of the bar function.
foo now actually refers to the local variable instead of the outer variable of the same name. But since the local hasn't been assigned yet, its value is undefined. Hence, when you try to invoke foo, you'll get a TypeError.
Nothing. Because you threw an error. That's it. Your code broke.
The arguments for Crockfords preference have been well made and are valid. I am just beginning to return to the first format now however, as I believe that for experienced developers who understand variable hoisting and are not likely to fall foul to it, there are 2 advantages that I can think of:
When new variables are added to the list of definitions, diffing is made easier. This means you are likely to experience fewer merge conflicts (simple though they may be to resolve) and less cognitive load when analysing diffs. For similar reasons I have also been converted to dangling commas, which I would never have expected xD
As #ldsenow identified, it can make searching for variable definitions more simple. You will always be able to search for var <name> and get the result you want and nothing else.

Why are arguments in JavaScript not preceded by the var keyword?

This may be a silly question, but why are function arguments in JavaScript not preceded by the var keyword?
Why:
function fooAnything(anything) {
return 'foo' + anyThing;
}
And not:
function fooAnything(var anything) {
return 'foo' + anyThing;
}
I have a feeling the answer is because that's what the Spec says but still...
Most dynamicaly-typed programming languages don't have explicit vars in the argument list. The purpose of the var keyword is to differentiate between "I am setting an existing variable" and "I am creating a new variable" as in
var x = 17; //new variable
x = 18; //old variable
(Only few languages, like Python, go away with the var completely but there are some issues with, for example, closures and accidental typos so var is still widespread)
But in an argument list you cannot assign to existing variables so the previous ambiguity does not need to be resolved. Therefore, a var declaration in the arguments list would be nothing more then redundant boilerplate. (and redundant boilerplate is bad - see COBOL in exibit A)
You are probably getting your idea from C or Java but in their case type declarations double up as variable declarations and the cruft in the argument lists is for the types and not for the declarations.
We can even get away with a "typeless, varless" argument list in some typed languages too. In Haskell, for example, types can be inferred so you don't need to write them down on the argument list. Because of this the argument list consists of just the variable names and as in Javascript's case we don't need to put the extraneous "let" (Haskell's equivalent to "var") in there:
f a b = --arguments are still variables,
-- but we don't need "let" or type definitions
let n = a + b in --extra variables still need to be declared with "let"
n + 17
It would be a redundant use of the var keyword. Items that appear in the parentheses that follow a function name declaration are explicitly parameters for the function.
The var keyword declares the scope of the variable. A function argument also introduces the scope for that argument. Hence there's no need for it, since it serves the same function.
I think the question comes up because we're used to seeing function bla (int i) in many languages. The same, syntactically, as the int i; somewhere in the function body to declare a variable. The two ints are however not doing the same; the first defines the type, the second defines type and the scope. If you don't have to declare the type, the scope-declaration still needs to happen (which is why we have var in the second case) but there is no information needed in front of arguments.

what is the difference in variable delaration here?

I am picking up maintenance of a project and reading code:
I see two methods of variable declaration. Can someone explain what the difference between the first and second line means?
To me, I am reading that in javascript, the var keyword is optional. in the first line, they have declared two new variables and initialized them. In the second line, they have declared two new varialbes but not have initialized them. Should I take anything more from this?
aURL = ""; msgNb = 1;
var mode, param, counter;
Unless all these variables are inside a function they're all globals, the first two are assignments which I would guess because they were previously declared, otherwise it may be shortened to
var aURL = '',
msgNb = 1,
mode,
param,
counter;
The unassigned ones have an undefined value by default.
You should always use the var keyword to keep the variable within the same function scope and not force it to become an implicit global, otherwise you could run into issues with duplicate variable naming and assignment.
If you're not using var then you're using (or creating) a variable from a "parent" scope, all the way up to being global if it doesn't find a local one at any scope.
This is not a "jquery" issue per say but rather a JavaScript issue. A variable without the "var" keyword has global scope, i.e., it is visible from all methods, objects, etc... A var is only visible within its specific scope.

Categories

Resources