How JavaScript closure works?

Tutorial about JavaScript closure with code examples and video
07 August 2017   991
JavaScript

Lightweight interpreted or JIT-compiled programming language with first-class functions

Closures are functions that refer to independent (free) variables. In other words, the function defined in the closure "remembers" the environment in which it was created.

Some facts:

  • A closure is one way of supporting first-class functions; it is an expression that can reference variables within its scope (when it was first declared), be assigned to a variable, be passed as an argument to a function, or be returned as a function result.

  • Or, a closure is a stack frame which is allocated when a function starts its execution, and not freed after the function returns (as if a 'stack frame' were allocated on the heap rather than the stack!).

Closure Examples

The following code returns a reference to a function:

function sayHello2(name) {
  var text = 'Hello ' + name; // Local variable
  var say = function() { console.log(text); }
  return say;
}
var say2 = sayHello2('Jim');
say2(); // logs "Hello Jim"

 In above code, a closure can be found here: the anonymous function function() { console.log(text); } is declared inside another function, sayHello2() in this example.

In JavaScript, You create a closure by using the function keyword inside another function

Please note: in C and most other common languages, after a function returns, all the local variables are no longer accessible because the stack-frame is destroyed.

But in JavaScript, if you create a function within another function, then the local variables can remain accessible after returning from the function you called. This is demonstrated above. Because say2() function was called after we have returned from sayHello2(). Notice that the code that we call references the variable text, which was a local variable of the function sayHello2().

function() { console.log(text); } // Output of say2.toString();

Looking at the output of say2.toString(), you can see that the code refers to the variable text. The anonymous function can reference text which holds the value 'Hello Jim' because the local variables of sayHello2() are kept in a closure.

The thing is that in JavaScript a function reference also has a secret reference to the closure it was created in — similar to how delegates are a method pointer plus a secret reference to an object. 

For some reason, closures  hard to understand when you read a plain text about them, but examples realy helps to understand their work. 

This example shows that the local variables are not copied — they are kept by reference. 

function say667() {
  // Local variable that ends up within closure
  var num = 42;
  var say = function() { console.log(num); }
  num++;
  return say;
}
var sayNumber = say667();
sayNumber(); // logs 43

All three global functions have a common reference to the same closure because they are all declared within a single call to setupSomeGlobals().

var gLogNumber, gIncreaseNumber, gSetNumber;
function setupSomeGlobals() {
  // Local variable that ends up within closure
  var num = 42;
  // Store some references to functions as global variables
  gLogNumber = function() { console.log(num); }
  gIncreaseNumber = function() { num++; }
  gSetNumber = function(x) { num = x; }
}

setupSomeGlobals();
gIncreaseNumber();
gLogNumber(); // 43
gSetNumber(5);
gLogNumber(); // 5

var oldLog = gLogNumber;

setupSomeGlobals();
gLogNumber(); // 42

oldLog() // 5

The three functions have shared access to the same closure — the local variables of setupSomeGlobals() when the three functions were defined.

Note that in the above example, if you call setupSomeGlobals() again, then a new closure (stack-frame!) is created. The old gLogNumbergIncreaseNumbergSetNumber variables are overwritten with new functions that have the new closure. (In JavaScript, whenever you declare a function inside another function, the inside function(s) is/are recreated again each time the outside function is called.)

Little advice: if everything is complitelly unclear, the best thing to do is to use the examples. Reading a text is much harder than understanding examples.

Also, you can look this video tutorial about JavaScript closures.

What is Vim.Wasm?

Small introduction to Vim port to WebAssembly with screenshot and developer notes
16 July 2018   91

Vim.wasm is experimental fork of Vim editor to compile it into WebAssembly using emscripten and binaryen.

Developer added some notices:

  • Please access from a desktop browser (Chrome/Firefox/Safari/Edge). Safari seems the best on macOS.
  • Please avoid mobile networks. Your browser will fetch some large files (up to 2.5MB).
  • vim.wasm takes key inputs from DOM keydown event. Please disable your browser extensions which affect key inputs (incognito mode would be the best).
  • This project is very early phase of experiment. Currently only tiny features are supported. More features will be implemented (please see TODO section). And you may notice soon on trying it... it's buggy :)
  • If inputting something does not change anything, please try to click somewhere in the page. Vim may have lost the focus.

The goal of this project is running Vim editor on browser by compiling Vim C sources into WebAssembly. 

Vim.wasm screenshot
Vim.wasm screenshot 

WebAssembly frontend for Vim is implemented as a new GUI frontend. C sources are compiled to each LLVM bitcode files and then they are linked to one bitcode file vim.bc by emccemcc finally compiles the vim.bc into vim.wasm binary using binaryen and generates HTML/JavaScript runtime.

You can find more info at GitHub.