June 19, 2024
TestsSource
- how far can we nest a closure?
- `var` vs. `let` in a closure?
- dynamically created closures
- block `{ }` has the same rules like closures?
Source Code
The source code we wrote during the event.
test.js
import {strict as assert} from 'assert';
describe('how far can we nest a closure?', () => {
it('an inner function has access to the parent function`s scope', () => {
function outer() {
let varInOuter = 42;
return function inner() {
varInOuter += 1;
return varInOuter;
}
}
assert.equal(outer()(), 43);
});
it('an 2nd level inner function has accces to the outer scope', () => {
function veryOuter() {
let varInVeryOuter = 42;
return function outer() {
varInVeryOuter += 1;
return function inner() {
varInVeryOuter += 1;
return varInVeryOuter;
}
}
}
assert.equal(veryOuter()()(), 44)
});
});
describe('`var` vs. `let` in a closure?', () => {
it('the inner function has access to the outer function`s scope even using `var`', () => {
function outer() {
var varInOuter = 42;
return function inner() {
varInOuter += 1;
return varInOuter;
}
}
assert.equal(outer()(), 43);
});
});
describe('dynamically created closures', () => {
it('using a for-loop and passing the loop variable to a closure makes each closure use the loop variable', () => {
const closures = [];
for (var i= 0; i<3; i++) {
closures.push(() => i);
}
assert.equal(closures[0](), 3);
assert.equal(closures[1](), 3);
assert.equal(closures[2](), 3);
});
it('creating a closure using `let` fixes the above "problem"', () => {
const closures = [];
for (let i= 0; i<3; i++) {
closures.push(() => i);
}
assert.equal(closures[0](), 0);
assert.equal(closures[1](), 1);
assert.equal(closures[2](), 2);
});
it('use an IIFE to fix the problem even using `var`', () => {
const closures = [];
for (var i= 0; i<3; i++) {
const newFunction = (function(newI) {
return function() {
return newI;
}
})(i);
closures.push(newFunction);
}
assert.equal(closures[0](), 0);
assert.equal(closures[1](), 1);
assert.equal(closures[2](), 2);
});
});
describe('block `{ }` has the same rules like closures?', () => {
it('an inner block has access to the outer block', () => {
{
let outerVar = 42;
{
assert.equal(outerVar, 42);
}
}
});
it('a block scoped `let` variable is not visible outside', () => {
{
let inside = 42;
}
assert.throws(() => {
inside;
}, ReferenceError);
});
it('a block scoped `var` var is visible outside', () => {
{
var inside = 42;
}
assert.equal(inside, 42);
});
});