Scope and Closure Flashcards

1
Q

what is the output?

function foo(a) {
	console.log( a + b );
	b = a;
}

foo( 2 );

A

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.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

what is “scope”

A

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.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

what does this do?

eval(..)

A

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

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

what is Lexical scope

A

Lexical scope means that scope is defined by author-time decisions of where functions are declared.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

what are the ways to cheat lexical scope?

A

Usage of eval and with keyword, where we are create variables inside functions

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Does JS support Block scope?

A

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

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

What is the output

{
   console.log( bar ); 
   let bar = 2;
}
A

Reference Error

Use of let keyword, doesn’t necessarily hoist a variable

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

What are the kinds of scoping available in JS?

A

“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

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Output of this?
a = 2;
var a;
console.log( a );

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
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

output of this

console.log( a );
var a = 2;
A

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

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

What is Hoisting

A

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”.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

The output of this program

foo();

var foo = function bar() {
	// ...
};
A

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.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Output of this function

foo();
bar();

var foo = function bar() {
	// ...
};
A

TypeError
ReferenceError
The code gets rewritten as

var foo;
foo(); bar(); 
foo = function() {
	var bar = ...self...
	// ...
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

What is the output?

foo();

function foo() {
	console.log( 1 );
}
var foo = function() {
	console.log( 2 );
};
function foo() {
	console.log( 3 );
}
A

3

subsequent function declarations do override previous ones.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q
What is teh output
for (var i=1; i<=5; i++) {
	setTimeout( function timer(){
		console.log( i );
	}, i*1000 );
}
A

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

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Relationship between this keyword and () => ?

A

Fat operator ignores all rules for “this”

instead take on the this value of their immediate lexical enclosing scope, whatever it is.

17
Q

another way to overcome the limitations associated with the this object while using arrow operators?

A
Use the bind keyword,
var obj = {
	count: 0,
	cool: function coolFn() {
		if (this.count < 1) {
			setTimeout( function timer(){
				this.count++; // `this` is safe because of `bind(..)`
				console.log( "more awesome" );
			}.bind( this ), 100 ); // look, `bind()`!
		}
	}
};

obj.cool();