Advanced JavaScript: scope, closures and this

Lexical scope and the scope chain, the closure that keeps its variables, the value of this depending on how the function is called, and the this lost inside a callback.

  • 29 cards
  • 5 topics
  • Free

The outline, topic by topic

Each topic is weighted the way the exam weighs it.

  1. Concepts
  2. Questions
  3. Sort and link
  4. Scenarios
  5. Understand

A few cards from the deck

  • Lexical scope: what is it?

    Show the answer

    The rule that the names visible inside a function depend on where it is written in the code, not on where it is called from.

    The engine can therefore tell, just by reading the file, which variable each name refers to.

  • What does this program print to the console?

    ```js
    function fabrique() {
    let n = 0;
    return () => ++n;
    }
    const c1 = fabrique();
    const c2 = fabrique();
    console.log(c1(), c1(), c2());
    `

    • 1 2 1
    • 1 2 3
    • 1 1 1
    • 0 1 0
    Show the answer

    1 2 1

    Each call to fabrique() creates its own n. c1 increments its own (1, then 2), c2 has another one that starts at 0 and gives 1.

  • let and const have … scope, whereas var has … scope.

    Show the answer

    let and const have block scope, whereas var has function scope.

    A var variable declared in an if or a loop stays visible in the whole function; let disappears at the closing brace.

  • Scope chain: what is it?

    Show the answer

    The sequence of nested scopes searched in order, from the innermost to the outermost, until the name being looked up is found.

    An inner variable with the same name hides an outer one (this is shadowing); if no scope holds the name, it is a ReferenceError.

  • Inside a class method, the code is charger().then(this.saluer). When the promise resolves, the console shows “TypeError: Cannot read properties of undefined (reading 'nom')” inside saluer, which reads this.nom. Which fix works?

    • Pass this.saluer() to then
    • Replace this.nom with nom inside saluer
    • Pass this.saluer.bind(this) to then
    • Pass saluer without the this. prefix
    Show the answer

    Pass this.saluer.bind(this) to then

    this.saluer gives the bare function, detached from its object: then calls it as a plain function and, since class code is in strict mode, this is undefined. bind(this) (or an arrow () => this.saluer()) keeps it. Writing this.saluer() would run the method right away and pass its result to then.