In JavaScript the execution of code takes in 2 phases. In first step it is read and the space is reserved for variables(given value undefined initially) and functions. In the second phase it is executed line by line.
And also I read that the variables declared without var keyword are set as Global variables.
So if I print a variable before defining it inside a function, it should print undefined. Like in the code below:
b();
console.log(a);
console.log(d);
var a = 'Hello World!';
function b() {
console.log(c);
console.log('Called b!');
var c = "variable c is printed";
console.log(c);
console.log(d);
d = "Variable d is printed";
}
I expect the output to be:
undefined
Called b!
variable c is printed
undefined
Variable d is printed
But I get the below output:
undefined
Called b!
variable c is printed
Uncaught ReferenceError: d is not defined
at b (app.js:12)
at app.js:1
So my doubt is, when function b is called, then in the first phase of code execution, variable d should be given space and value undefined initially. And then the execution should begin line by line in the second phase.
And also I read that the variables declared without var keyword are set as Global variables.
Yes, kind of. What happens is that if you do an assignment, like
d = 1;
The engine goes up through all environment records (the place were values of variables are stored at runtime), so in your case it first goes to bs record, and then to the global record. If it finds a variable binding (name -> value) in one of those records (which were created when execution starts, just as you said), it then stores the value there. However if it reaches the global record, and does not find a binding along the way (the variable is undeclared), it just creates a new binding at that global record.
So by the time you do console.log(d), no binding for d exists, and accessing d fails.
In first Phase When try to set space for Variables Find them by Keywords:
var/let/const
When you don't use it in second Phase crashed variables pointer where not exist space for them, In function scope d don't have any space and its a crash point.
this code show what happened:
console.log(a);
a = 'Some Value For A Variable';
to solve it two solution:
1- use Keywords
console.log(a);
var a = 'Some Value For A Variable';
2- Initializing First
a = 'Some Value For A Variable';
console.log(a);
The Best Clear Code is Complex of two Solution:
* use keywords
* call variables after definition
var a = 'Some Value For A Variable';
console.log(a);
Good Luck
Related
This is a serious question, It has been nagging me for a while. In JavaScript you can declare a variable which has no type. It's type is often dynamic, depends on further value assigned to it.
e.g
var text;
typeof(text); //undefined
text = 'someText';
typeof(text); //string
So as we know that Javascript can dynamically change variable's type why these assignments are invalid then?
e.g
var someObj;
someObj.a = 'hello world';
console.log(someObj) //TypeError
var someTable;
someTable[0] = 'hello world';
console.log(someTable[0]) //TypeError
where this problem can be fixed just by adding definition to variable declaration:
var someObj = {};
var someTable = [];
I'd expect a good explanation of this problem. Thanks for answers.
There's a big difference between declaration and initialisation of variables.
When you declare a variable without initializing it with a value, its type will be undefined, so when you will try to call it or access it, it will give undefined, because simply there were no value defined for the variable.
That's why it should be initialized:
var someObj = {};
var someTable = [];
So you can treat it as a string, an object or an array according its initialized value.
Documentation:
Please take a look at variables MDN Reference for further reading, where it says:
A var statement declares variables that are scoped to the running execution context’s VariableEnvironment. Var variables are created when their containing Lexical Environment is instantiated and are initialized to undefined when created. [...] A variable defined by a VariableDeclaration with an Initializer is assigned the value of its Initializer’s AssignmentExpression when the VariableDeclaration is executed, not when the variable is created.
You're getting confused about where the error is thrown. In your first example:
var someObj;
someObj.a = 'hello world'; // the error is thrown here
That error is thrown because someObj is undefined (not undeclared). So, you can't access the property a on undefined.
The same explanation applies for your second example:
var someTable;
someTable[0] = 'hello world'; // the error is thrown here
You're trying to access index 0 of undefined.
The reason that defining them as {} and [], respectively, fixes your issue, is that you are then accessing property a of {} and index 0 of [].
1) Data types in Javascript are not dynamic, they are mutable. This means that depending on kind of operation you are applying to them they can change from being something into another thing (e.g. a number can become a string doing something like this: 4 + 'a').
2) The "error" is a consequence of having a variable not initialized. In Javascript when you are doing this:var something = 'a'
you are doing two operations, a declaration, and an assignment. If you don't do the assignment and you try to access to a property of the object you have declared it will throw an error. In your case, you are declaring a variable but not initializing it to the "compiler" can't access the "a" property or the position 1 because it is of type undefined.
These are 2 examples which must have attained same result:
Example 1
<script>
console.log(a);
var a = 10;
console.log(a);
</script>
Rendered
<script>
var a = "";
console.log(a); //will result undefined
a = 10;
console.log(a); //will result 10
</script>
Result
undefined
10
Example 2
<script>
console.log(a);
a = 10;
console.log(a);
</script>
Expectation of Rendering
<script>
var a = "";
console.log(a); //should result undefined
a = 10;
console.log(a); //should result 10
</script>
Result
Now, as per JS Hoisting in Scenario 2, the variable if not declared must have been automatically declared onto top of its scope and still result should have been the same. Why is it not? Where is the concept failed?
The second case is different, because
a = 10
... does not declare a hoisted variable. It creates a property in the window object (even if the code would have been inside a function). This is not a declaration, and thus something that is not hoisted. So before you create that property, it does not exist.
Note that what you listed as rendered code is not entirely correct. A hoisted variable does not get a value, so for your first example it should look like this:
var a; // undefined!
console.log(a); // will output undefined
a = 10;
console.log(a); // will output 10
Note that if this code is not part of a function body, var a also creates the window.a property, and this happens at the hoisted declaration.
And for your second example, the rendered code could look like this
console.log(a); // Error: does not exist.
window.a = 10;
console.log(a); // will output 10
JavaScript hoists declarations, not initializations, see this page.
If you add a 'var a;' somewhere in your second example, it should work fine!
On example 2, at the time you run the first console log, a is really undefined.
a = 10 sets a new property a to the window object and there's no 'hoisting' when setting a property to an object that already exists.
when we will execute a source code .IN hoisting, The declaration variable goes over console.log().Then the variable allowcated a memory but does not access it. When I declaration a variable in memory. Then we give by default undefined value in place of that variable. (as like ,in html,place Holder works like this.
--- So you have not declared any variable. Hosting will not work here.
--- Can't access a here..Because when you define a variable.
Then you must be defined a variable.here u can not make variable so output: cannot access a
Please let me know the difference between the below two codes.
var a = 1;
function b() {
a = 10;
return;
}
b();
console.log(a);
This prints 10 in console.
whereas the below code prints 1 in console
var a = 1;
function b() {
var a = 10;
return;
function a() {}
}
b();
console.log(a);
Thanks for help.
In the first code there is one global variable 'a' which can be modified by any function and that change would be permanent.
But in the second code, there are two 'a' variable. Lets call them ag (a global) and al (a local). In second code b() function is modifying al (local variable a) not the global variable. But we are printing global variable in console.
Thats why results are varying in both the codes.
It's a metter of scope. In the first a is declared only out of function b, so when you edit a inside function b you are referencing the "outer" a.
In the second snippet you are re-declaring var a inside the function, so when you edit a variable inside the b function you are referencing the latest leaving untouched the "outer" a variable.
You have declared a in your second code inside the function hence the scope(availability) of your variable a persists only till function execution.
Once we return back from the function, local variable a is no more hence outer global a's value is printed.
when you are using var ,its scope will be local to its function.
and without var it will be a global function.
The first example is quite straight-forward: You declare an a variable which your b function closes over. So b sets a to 10.
Your second example is deliberately complex and confusing. You declare an a variable that b closes over, but then shadow it with an a variable inside b. To make matters worse, there's also a function declaration of a that is also in scope in b. The var wins over the function declaration, because function declarations are processed before var statements are. The outer a is completely unaffected by b, so the console.log at the end logs 1.
That's easier to describe with a diagram of sorts:
var a = 1; // <== The declaration `b` closes over
function b() {
var a = 10; // <== The inner `a` variable
return; // <== Returns from `b`
function a() {} // <=== Declaration that was processed immediately
// upon entering `b` (the `return` doesn't affect it
// at all), but which is then superceded by `var a`
}
b();
console.log(a); // Logs 1
Why does the following code result in logging of b while a is still undefined?
(function(){ var a=b=5; })();
console.log('b:'+b);
console.log('a:'+a);
Because var a=b=5; statement defines only local a variable and in fact is interpreted like
var a = (b=5);
which equals to
b = 5;
var a = 5;
which assigns 5 to a global b variable and defines a local a variable.
The proper way to define 2 local variables without value repetition would be
var b = 5, a = b;
In JavaScript if you ommit the var keyword before a variable, it will be considered as global.
So here b is a global variable and a is only a local to that function's scope.
That's why you are getting the error while accessing the a.
Never mind, I figured it out myself as it wouldn't let me sleep.
There are 2 assignments happening within the IIFE whereas only 1 declaration.
The statement var a=b=5; declares the variable a with var but simply does assignment for the other variable b.
b is actually never declared here, just assigned - making it a global variable.
Hence b is accessible to the log statement outside the function, which prints its value as 5.
In other words, under 'strict' mode, the code will look like this:
(function() {
'use strict';
var a = window.b = 5;
})();
console.log(b);
A variable can be defined in 2 ways:
var a= 5 // first
a=5 // Second
In first way, a is a local variable, but in second way, it becomes a global variable.
So, when you do var a=b=5, b is a global variable and hence retains value.
Is this a variable definition or declaration? And why?
var x;
..and is the memory reserved for x after this statement?
EDIT:
In C extern int x; is a declaration, int x = 5; is a definition. What's the analog in JS? Wikipedia says a declaration allocates memory and the definition assigns a value to this allocated memory.
SECOND EDIT:
I think the explanation of #Deryck sounds great, but there's some output that disagrees with his explanation:
> var x;
undefined
> x
undefined // now it looks like x is defined to the value undefined
> y
ReferenceError: y is not defined
If the ReferenceError output would say y is not declared it would make sense. But often I read that JS has two non-values: null and undefined. So var x would be a definition with the value undefined.
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
PS - your analogy between C variable dec/def and JS was spot on. What you read on Wikipedia was correct.
Declaring a variable is like telling the (javascript) compiler that this token x is something I want to use later. It does point to a location in memory, but it does not yet contain a value. ie. it is undefined
var x;
defining it means to give it a value which you can either do it like:
x = 10; // defining a variable that was declared previously
or like this:
var y = 20; // declaring and defining a variable altogether.
http://msdn.microsoft.com/en-us/library/67defydd(v=vs.94).aspx
http://www.w3schools.com/js/js_variables.asp
I will give you a long answer for better explanation.
When the javascript engine is not able to find a particular variable in memory, it will throw an error. To be more specific, when the javascript engine (Execution Context) is not able to "reference" a variable in memory, it will throw a ReferenceError. This is not exactly the same as a Declaration Error, at least in javascript.
There is a deference between a not defined error and the value undefined.
So doing
var a = undefined;
and
var a;
will both log the same result i.e. undefined. This is because, when you simply do a var a; the javascript engine allocates memory for the variable and automatically sets it's value to undefined, which is different from saying that a doesn't exist at all - in which case it will throw a ReferenceError.
Hoisting
console.log(a); // undefined
var a = 'something';
will log undefined because, the javascript engine knows there's a variable declared somewhere in the code - which means to say that the javascript engine actually does something before it executes the code - one of the thing it does is hoists variables. To put it simply, the above code is the same as
var a; // hoisted (declared and defined the value `undefined`)
console.log(a); // undefined
a = 'something' // update the defined value to `something`
So, yes, declaration and definition happen together in javascript (automatically - if you don't do it yourself) and the default defined value is undefined.
ES6
Just an additional note
const a;
will throw a SyntaxError where a initializer (definition) is necessary. const is the only time when you need to declare and define manually.
> var x;
undefined
> x
undefined // now it looks like x is defined to the value undefined
> y
ReferenceError: y is not defined
Although it is usually said that Javascript is an interpreted language, but there is also a compilation step that happens very fast just before the interpreter runs. The job of this compilation step is to create scope chains, where variables are declared(no read/write operation here, just simple name-keeping) in their respective scopes. These variables will point to some memory location but value in it will be undefined until some execution is carried out by the interpreter.
> Compiler run:
When compiler sees var x;, it will simply book-keep this variable in its respective scope.
The next x; and y; are simply ignored in the compilation step as they are execution statements.
> Interpreter run:
When interpreter sees var x;, it will skip this as there is no read/write operation here.
Now when interpreter sees x;(execution statement), "x" will already be declared in the scope, and it will hold value "undefined", which is what you get on the console.
But when interpreter sees y; similarly, there has been no previous declaration or name-keeping for it in the compilation step, and thus we get the ReferenceError as expected.
Hope someone finds this comment useful.
var x, y, z;
var x;
var h = 4;
i = 4;
all the above are global variables if placed at the top, (outside any functions)
Lets say that the javascript has a function start
function start() {
x = 5*5;
}
the global variable x is now equal to 25
Where as if the var x; was not placed outside of any functions, that variable x would just be local to that function.
You declare JavaScript variables with the var keyword:
var carname;
After the declaration, the variable is empty (it has no value).
To assign a value to the variable, use the equal sign
var carname="Volvo";
In computer programs, variables are often declared without a value. The value can be something that has to be calculated, or something that will be provided later, like user input. Variable declared without a value will have the value undefined.
The variable carname will have the value undefined after the execution of the following statement:
var carname;
var hoisting
In JavaScript, a variable can be declared after being used.
bla = 2
var bla;
// ...
// is implicitly understood as:
var bla;
bla = 2;
For that reason, it is recommended to always declare variable at the top of functions. Otherwise, it may lead to confusing cases
When declaring a variable without assigning a value to it, there still needs to be some memory available for it, otherwise you cannot make a reference to the variable later in the program. I don't think it's a noticeable amount of memory being used and won't make a difference.
var x;
This is a variable declaration. In Js if you don't assign any value to variable in declaration. It will get undefined by default.
var x; // declaring x
console.log(x); // output: undefined
But if you have not even declared the variable in you try to access it. It says that the variable is not defined.
console.log(y); // Output: ReferenceError: y is not defined
If you need access to objects between JS files, it's good practice to expose one object to the global namespace and declare fields and methods on that object.
File 1:
var myObject;
myObject.myField = "Field!";
File 2:
myObject.prototype.myFunction = function () {
return this.myField;
};
I have taken from a really good discussion on : Equivalent of C extern declaration in JavaScript
https://github.com/ganqqwerty/123-Essential-JavaScript-Interview-Questions
Various trivia regarding the difference between undefined and null completely aside, the short answer is: there is no equivalence in Javascript. There are no bare "forward declarations". Javascript variable declarations are definitions. Variables that have been defined but not explicitly initialized will contain the value 'undefined'. There is no "external linkage".
If you refer to an identifier that is not in any accessible scope (perhaps because it doesn't exist the first place), you will get your "ReferenceError: y is not defined". This has nothing to do with variable value or storage.
In simple terms,
undefined means value to the variable is not defined.
not defined means the variable itself is not defined.
var x; //value is not defined. So,
x //undefined
//y variable is not declared or defined. So,
y // y is not defined