Typescript
  • Introducão
  • Primeiros Passos
    • Por que TypeScript
  • JavaScript
    • Igualdade
    • Referências
    • Null vs. Undefined
    • this
    • Closure
    • Number
    • Truthy
  • Futuro JavaScript Agora
    • Classes
      • Classes Emit
    • Arrow Functions
    • Rest Parameters
    • let
    • const
    • Destructuring
    • Spread Operator
    • for...of
    • Iterators
    • Template Strings
    • Promise
    • Generators
    • Async Await
  • Project
    • Compilation Context
      • tsconfig.json
      • Which Files?
    • Declaration Spaces
    • Modules
      • File Module Details
      • globals.d.ts
    • Namespaces
    • Dynamic Import Expressions
  • Node.js QuickStart
  • Browser QuickStart
  • TypeScript's Type System
    • JS Migration Guide
    • @types
    • Ambient Declarations
      • Declaration Files
      • Variables
    • Interfaces
    • Enums
    • lib.d.ts
    • Functions
    • Callable
    • Type Assertion
    • Freshness
    • Type Guard
    • Literal Types
    • Readonly
    • Generics
    • Type Inference
    • Type Compatibility
    • Never Type
    • Discriminated Unions
    • Index Signatures
    • Moving Types
    • Exception Handling
    • Mixins
  • JSX
    • React
    • Non React JSX
  • Options
    • noImplicitAny
    • strictNullChecks
  • Errors in TypeScript
    • Interpreting Errors
    • Common Errors
  • NPM
  • Testing
    • Jest
    • Cypress
  • Tools
    • Prettier
    • Husky
    • Changelog
  • TIPs
    • String Based Enums
    • Nominal Typing
    • Stateful Functions
    • Bind is Bad
    • Currying
    • Type Instantiation
    • Lazy Object Literal Initialization
    • Classes are Useful
    • Avoid Export Default
    • Limit Property Setters
    • outFile caution
    • JQuery tips
    • static constructors
    • singleton pattern
    • Function parameters
    • Build Toggles
    • Barrel
    • Create Arrays
    • Typesafe Event Emitter
  • StyleGuide
  • TypeScript Compiler Internals
    • Program
    • AST
      • TIP: Visit Children
      • TIP: SyntaxKind enum
      • Trivia
    • Scanner
    • Parser
      • Parser Functions
    • Binder
      • Binder Functions
      • Binder Declarations
      • Binder Container
      • Binder SymbolTable
      • Binder Error Reporting
    • Checker
      • Checker Diagnostics
      • Checker Error Reporting
    • Emitter
      • Emitter Functions
      • Emitter SourceMaps
    • Contributing
Powered by GitBook
On this page

Was this helpful?

  1. JavaScript

Closure

The best thing that JavaScript ever got was closures. A function in JavaScript has access to any variables defined in the outer scope. Closures are best explained with examples:

function outerFunction(arg) {
    var variableInOuterFunction = arg;

    function bar() {
        console.log(variableInOuterFunction); // Access a variable from the outer scope
    }

    // Call the local function to demonstrate that it has access to arg
    bar();
}

outerFunction("hello closure"); // logs hello closure!

You can see that the inner function has access to a variable (variableInOuterFunction) from the outer scope. The variables in the outer function have been closed by (or bound in) the inner function. Hence the term closure. The concept in itself is simple enough and pretty intuitive.

Now the awesome part: The inner function can access the variables from the outer scope even after the outer function has returned. This is because the variables are still bound in the inner function and not dependent on the outer function. Again let's look at an example:

function outerFunction(arg) {
    var variableInOuterFunction = arg;
    return function() {
        console.log(variableInOuterFunction);
    }
}

var innerFunction = outerFunction("hello closure!");

// Note the outerFunction has returned
innerFunction(); // logs hello closure!

Reason why it's awesome

It allows you to compose objects easily e.g. the revealing module pattern:

function createCounter() {
    let val = 0;
    return {
        increment() { val++ },
        getVal() { return val }
    }
}

let counter = createCounter();
counter.increment();
console.log(counter.getVal()); // 1
counter.increment();
console.log(counter.getVal()); // 2

At a high level it is also what makes something like Node.js possible (don't worry if it doesn't click in your brain right now. It will eventually 🌹):

// Pseudo code to explain the concept
server.on(function handler(req, res) {
    loadData(req.id).then(function(data) {
        // the `res` has been closed over and is available
        res.send(data);
    })
});
PreviousthisNextNumber

Last updated 6 years ago

Was this helpful?