1. Does the function select the latest content?

The function sayHi uses external variables. Which value will be used when the function runs?

let name = "John";

function sayHi() {
  alert("Hi, " + name);
}

name = "Pete";

sayHi(); // What will be displayed: "John" or "Pete"?
Copy the code

This situation is common in both browser and server-side development. A function may be scheduled to be executed some time after its creation, such as after user action or network request.

So the question is: will it receive the latest changes?


2. What variables are available?

The following makeWorker function creates another function and returns it. You can call this new function elsewhere.

Can it access external variables from where it was created or called (or both)?

function makeWorker() {
  let name = "Pete";

  return function() {
    alert(name);
  };
}

let name = "John";

// create a function
let work = makeWorker();

// call it
work(); // What will be displayed?
Copy the code

Which value will be displayed? “Pete” or “John”?


3. Is Counter independent?

Here we create two counters using the same makeCounter function: counter and counter2.

Are they independent? What does the second counter show? 0,1, 2,3 or something else?

function makeCounter() {
  let count = 0;

  return function() {
    return count++;
  };
}

let counter = makeCounter();
let counter2 = makeCounter();

alert( counter() ); / / 0
alert( counter() ); / / 1

alert( counter2() ); // ?
alert( counter2() ); // ? 
Copy the code

4. Counter object

Here we create a counter object through the constructor.

Does it work? What will it show?

function Counter() {
  let count = 0;

  this.up = function() {
    return ++count;
  };
  this.down = function() {
    return --count;
  };
}

let counter = new Counter();

alert( counter.up() ); // ?
alert( counter.up() ); // ?
alert( counter.down() ); // ?
Copy the code

5. Function inside if

Take a look at the code below. What is the result of the last line of code?

let phrase = "Hello";

if (true) {
  let user = "John";

  function sayHi() {
    alert(`${phrase}.${user}`);
  }
}

sayHi(); 
Copy the code

6. Closure sum

Write a sum function that works like sum(a)(b) = a+b.

Yes, that’s the way through double parentheses (not a mistake).

Here’s an example:

sum(1)(2) = 3
sum(5)(-1) = 4
Copy the code

7. Are variables visible?

What would be the result of the following code?

let x = 1;

function func() {
  console.log(x); // ?

  let x = 2;
}

func();
Copy the code

The P.S. mission has a catch. The solution is not obvious.


Answer and analysis

1. Answer:Pete.

The function looks inside out for the target variable in the corresponding lexical environment, using the latest value.

Old variable values are not stored anywhere. When a function wants a variable, it gets the current value from its own lexical environment or from an external lexical environment.


2. The answer:Pete.

The function work() in the code below gets name from the external lexical environment reference where it was created:

So the result here is zero"Pete".

But if there is no let name in the makeWorker(), the search continues and the global variable is eventually found, as we can see in the figure above. In this case, the result will be “John”.


3. The answer:0, 1.

The functions counter and Counter2 are created through separate calls to makeCounter.

Therefore, they have independent external lexical environments, each with its own count.


1. 4. Smart trashes

Both nested functions are created in the same lexical environment, so they can share access to the same count variable:

function Counter() {
  let count = 0;

  this.up = function() {
    return ++count;
  };

  this.down = function() {
    return --count;
  };
}

let counter = new Counter();

alert( counter.up() ); / / 1
alert( counter.up() ); / / 2
alert( counter.down() ); / / 1
Copy the code

5. The answer:error.

The function sayHi is declared inside if, so it only exists in if. There is no sayHi on the outside.


6. For the second parenthesis to be valid, the first parenthesis must return a function.

Something like this:

function sum(a) {

  return function(b) {
    return a + b; // Get "A" from the external lexical context
  };

}

alert( sum(1) (2));/ / 3
alert( sum(5) (-1));/ / 4
Copy the code

7. Answer:error.

Run it:

let x = 1;

function func() {
console.log(x); // ReferenceError: Cannot access 'x' before initialization
  let x = 2;
}

func();
Copy the code

In this example, we can observe a special difference between a “nonexistent” variable and an “uninitialized” variable.

As you may have learned from variable scope, closures, variables begin to enter an “uninitialized” state the moment a program executes into a code block (or function). It remains uninitialized until the program executes to the corresponding LET statement.

In other words, a variable exists from a technical point of view, but is not available before LET.

The following code proves this.

Function func() {function func() {function func() {function func() {function func() {function func() {function func() {function func() {function func() {function func() {function func() { // ReferenceError: Cannot access 'x' before initialization let x = 2; }Copy the code

Areas where variables are temporarily unavailable (from the beginning of a code block to the LET) are sometimes referred to as “dead zones.”