Scope and Closure Flashcards
what is the output?
function foo(a) { console.log( a + b ); b = a; }
foo( 2 );
When the RHS look-up occurs for b the first time, it will not be found. This is said to be an “undeclared” variable, because it is not found in the scope.
If an RHS look-up fails to ever find a variable, anywhere in the nested Scopes, this results in a ReferenceError being thrown by the Engine. It’s important to note that the error is of the type ReferenceError.
By contrast, if the Engine is performing an LHS look-up and arrives at the top floor (global Scope) without finding it, and if the program is not running in “Strict Mode” [^note-strictmode], then the global Scope will create a new variable of that name in the global scope, and hand it back to Engine.
what is “scope”
as the set of rules that govern how the Engine can look up a variable by its identifier name and find it, either in the current Scope, or in any of the Nested Scopes it’s contained within.
what does this do?
eval(..)
The eval(..) function in JavaScript takes a string as an argument, and treats the contents of the string as if it had actually been authored code at that point in the program
what is Lexical scope
Lexical scope means that scope is defined by author-time decisions of where functions are declared.
what are the ways to cheat lexical scope?
Usage of eval and with keyword, where we are create variables inside functions
Does JS support Block scope?
Yes at times, with the usage of “with” keyword and in tray catch blocks.
Usage of let key-word gives the variable visibility only inside the block where they are defined
const key-word also gives the variables scope
What is the output
{ console.log( bar ); let bar = 2; }
Reference Error
Use of let keyword, doesn’t necessarily hoist a variable
What are the kinds of scoping available in JS?
“Function Scoping” and “Block Scoping”
variables defined inside a function have visibility only inside the function, whereas for Block scoping to work, the use of let, const or with(now deprecatetd) keywords are required
Output of this?
a = 2;
var a;
console.log( a );
2
Because of Hoisiting.
Hoisting moves the declarations to the top of the code, but the assignments, happen only in the flow.
The code actually gets rewritten as var a; a=2; console.log(a); so the output is 2
output of this
console.log( a ); var a = 2;
undefined
Hoisting and since only the declarations are moved to the top.
Following code gets rewritten and executed in the following order
var a
console.log(a)
a= 2
What is Hoisting
Variable and function declarations are “moved” from where they appear in the flow of the code to the top of the code. This gives rise to the name “Hoisting”.
The output of this program
foo();
var foo = function bar() { // ... };
TypeError.
The variable identifier foo is hoisted and attached to the enclosing scope (global) of this program, so foo() doesn’t fail as a ReferenceError. But foo has no value yet (as it would if it had been a true function declaration instead of expression). So, foo() is attempting to invoke the undefined value, which is a TypeError illegal operation.
Output of this function
foo();
bar();
var foo = function bar() { // ... };
TypeError
ReferenceError
The code gets rewritten as
var foo; foo(); bar(); foo = function() { var bar = ...self... // ... }
What is the output?
foo();
function foo() { console.log( 1 ); }
var foo = function() { console.log( 2 ); };
function foo() { console.log( 3 ); }
3
subsequent function declarations do override previous ones.
What is teh output for (var i=1; i<=5; i++) { setTimeout( function timer(){ console.log( i ); }, i*1000 ); }
6, printed out 5 times
Because all the time out methods execute after the completion of the loops
What’s missing is that we are trying to imply that each iteration of the loop “captures” its own copy of i, at the time of the iteration. But, the way scope works, all 5 of those functions, though they are defined separately in each loop iteration, all are closed over the same shared global scope, which has, in fact, only one i in it.
To make its work ass expected, for (var i=1; i<=5; i++) { (function(j){ setTimeout( function timer(){ console.log( j ); }, j*1000 ); })( i ); }
or use => in set timeout to create a own scope for each call