Scope & Closures Flashcards

1
Q

Define scope.

A

Scope is the accessibility of variables, functions, and objects in some particular part of your code during runtime. If a variable or expression is not in the current scope then it is unavailable for use.

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

True or false: scope is created by a function/code block?

A

True. Here, ‘count’ belongs to a scope created by foo(). Outside the foo() scope, count is inaccessible.

function foo() {
  let count = 0;
  console.log(count);
}
foo();
console.log(count); // ReferenceError
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

What are the two types of scope?

A

Global and local. A variable is in the global scope if it’s defined outside of a function.

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

When you nest a function inside another a function, are the variables of the outer scope accessible inside the inner scope?

function outerFunc() {
  let outerVal = 'I am outside!';
  function innerFunc() {
    console.log(outerVal);
  }

innerfunc();
}
outerFunc();

A

Yes. In that example, it will log “I am outside!”

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

What kind of scoping mechanism does JavaScript use?

A

Lexical scoping.

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

What is lexical scoping?

A

Lexical scope is determined at lexing time, which is a phase of compilation that converts a stream of characters into a stream of tokens.

Lexical scope is based on where variables and blocks of scope exist at author time. The engine determines the nesting of scope just by looking at the JavaScript source code, without executing it.

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

What is a closure?

A

A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment) so that it can access its lexical scope even when executed outside of its lexical scope.

function makeAdder(x) {
  return function(y) {
    return x + y;
  }
}
const add5 = makeAdder(5);
console.log(add5(2)); // 7

The inner function above maintains a reference to its lexical environment, which contains the variable x. That makes the inner function a closure because it closes over (captures, remembers) the variable x from it lexical scope.

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

What do you call a function that remembers the variables from the place where it was defined, regardless of where it is executed later?

A

A closure.

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

What’s a good way to identify a closure?

A

If you see a function with an alien variable (not defined inside the function), most likely the function is a closure because the alien variable is captured.

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

Name two uses of closures.

A

(1) Partial application: The process of applying a function to some of its arguments. The partially applied function gets returned for later use.
(2) Data privacy: Storing items in the lexical environment of that is not accessible outside the outer function.

const counter = (function() {
  var privatecounter = 0;
  function changeBy(val) {
    privatecounter += val;
  }

return {
increment: function() { changeBy(1); },
value: function() { return privateCounter; }
})();

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

Why does this for loop log the same value (3) each time? What are two ways of fixing it so it logs 0 then 1 then 2?

for (var i = 0; i < 3; i++) {
  setTimeout(() => {
    console.log(i);
  }, 1000);
}
A

Closures created in a loop share the same lexical environment. The variable ‘i’ is not scoped to the inside of the for loop. It is scoped at the function level since it was defined by var. So there is just one variable whose value gets updated each time you go through the loop.

To fix it you need the closure to bind the variable to a tighter scope. For example, you could use ‘let’ so that ‘i’ is block-scoped.

for (let i = 0; i < 3; i++) {
  setTimeout(() => {
    console.log(i);
  }, 1000);
}

Or you could get the ‘i’ in function scope by using an immediately invoked function expression (IIFE).

for (var i = 0; i < 3; i++) {
  (function() {
    console.log(i);
  })();
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly