Published
Edited
Mar 12, 2020
Insert cell
Insert cell
Insert cell
{
const pizza = 'pepperoni'
// this is a block scope
{
// I can define a const with the same name
const pizza = '🍕'
expect(pizza).to.equal('🍕')
}
// the block did not affect the upper variable
expect(pizza).to.not.equal('🍕')
// pizza is unchanged
expect(pizza).to.equal('pepperoni')
return success()
}
Insert cell
Insert cell
Insert cell
{
const pizza = 'pepperoni'
// for fun lets enter in either block randomly
if (Math.random() < 0.5) {
const pizza = '🍕'
expect(pizza).to.equal('🍕')
} else {
const pizza = 'calzone';
expect(pizza).to.not.equal('🍕')
}
expect(pizza).to.equal('pepperoni')
return success()
}
Insert cell
Insert cell
{
const pizza = 'pepperoni'
for (let i = 0; i < 2; i++) {
let pizza = '🍕'
}
expect(pizza).to.equal('pepperoni')
return success()
}
Insert cell
Insert cell
{
let pizza = 'pepperoni'
function bake() {
let pizza = '🍕'
}
bake()
expect(pizza).to.equal('pepperoni')
return success()
}
Insert cell
md`If a variable is declared globally. It can be accessed directly within a function. It can even be reassigned`
Insert cell
{
let pizza = 'pepperoni'
function bake() {
expect(pizza).to.equal('pepperoni')
pizza = '🍕'
}
bake()
expect(pizza).to.equal('🍕')
return success()
}
Insert cell
md`This is the same behavior for every scope we saw`
Insert cell
{
let pizza = 'pepperoni'
{
pizza = '🍕'
}
expect(pizza).to.equal('🍕')
return success()
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
const baking = new Set()
function bake(value, elem) {
// ba
baking.add(value)
const className = 'moveToResult'

if (elem.classList.contains(className)) return
// afterAnimation is just a function to animate the addings of ingredients with a nice movement.
// the function is declared at the bottom of this notebook
const afterAnimation = animate({ elem, className, destination: '#result_issue'})
// innerHTML gets setted only when there are 3 different items in the Set
afterAnimation(() => baking.size === 3 && (document.getElementById('result_issue').innerHTML = '🍕'), /* --animation-delay */ 1.8)
}
function setupBakery() {
const ingredientsArray = Object.entries(ingredients_issue)
for (var [id, value] of ingredientsArray) {
document.getElementById(id).onclick = function(event) {
// item is scoped to setupBakery lexical environment
// var id and var value where hoisted and are declared before the for loop
// therefore value is always equal to "undefined"
bake(value, event.target)
}
}
}
setupBakery()
return success()
}
Insert cell
md`### Solution 1

There are many possibilities to address the above error, the first is to use *let* instead of *var* in the for loop
`
Insert cell
{
const ingredientsArray = Object.entries(ingredients_issue)
for (let [id, value] of ingredientsArray) {
// ...
}
return success()
}
Insert cell
Insert cell
{
const ingredientsArray = Object.entries(ingredients)
ingredientsArray.forEach(([id, value]) => {
// ...
})
return success()
}
Insert cell
md`### Solution 3

Another solution to this problem is to use closures.
`
Insert cell
Insert cell
Insert cell
{
const baking = new Set()
function bake(value, elem) {
baking.add(value)
const className = 'moveToResult'

if (elem.classList.contains(className)) return

const afterAnimation = animate({ elem, value, className, destination: '#result'})
afterAnimation(() => baking.size === 3 && (document.getElementById('result').innerHTML = '🍕'), /* --animation-delay */ 1.8)

}

// The below arrow function can be expanded to
// function pressButton(value) {
// return function (event) {
// bake(value, event.target)
// }
// }
const pressButton = value => event => bake(value, event.target)

function setupBakery() {
const ingredientsArray = Object.entries(ingredients)
for (var [id, value] of ingredientsArray) {
document.getElementById(id).onclick = pressButton(value)
}
}
setupBakery()
// click all the buttons
//ingredients.forEach(x => document.getElementById(x.id).click())
// this throws
//expect(document.getElementById('result').innerHTML).to.equal('🍕')
return success()
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more