Scoping with code blocks


I was browsing the THREE.js docs and stumbled across a pattern when researching how to create shadows.

The code looked a little something like this:

const scene = new THREE.Scene();

// ...

{
  const light = new THREE.DirectionalLight(0xffffff, 1);
  light.position.set(0, 10, 0);
  scene.add(light);
}

// ...

{
  const light = new THREE.AmbientLight(0xffffff, 0.5);
  scene.add(light);
}

// ...

What are the seemingly useless curly braces for? You could just rename the lights and be done with it, right?

const scene = new THREE.Scene();

// ...

const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(0, 10, 0);
scene.add(directionalLight);

// ...

const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);

// ...

From a technical perspective, this will work as well. But fiddling around with a 3d scene, you’ll likely have a lot of lights or other objects falling in the same category.

Good luck coming up with a unique name for each of them.


At first, playing around with the example code, I tried to arrange the lights like I knew. As few nested scopes as possible and rename everything. But then adding a light or changing the order of lights was unnecessarily hard.

Instead of trying to come up with a unique name for each light, you can scope one light at a time with curly braces. When you want to switch the order of the code blocks - in most cases - you should be fine.

This example is, next to the IIFE pattern, a simple way to scope your variables easily. By limiting the scope of the variable, you not only shorten the naming process, but you also limit the cognitive space you have to keep track of while constructing a solution.


You can even nest them if you want to:

const scene = new THREE.Scene();

// ...

{
  const lightGroup = new THREE.Group();
  scene.add(lightGroup);

  {
    const light = new THREE.DirectionalLight(0xffffff, 1);
    light.position.set(0, 10, 0);
    lightGroup.add(light);
  }

  {
    const light = new THREE.AmbientLight(0xffffff, 0.5);
    lightGroup.add(light);
  }
}

// ...

{
  const light = new THREE.AmbientLight(0xffffff, 0.5);
  scene.add(light);
}

// ...

With this in mind, maybe try limiting the scope of your variables more often.

Cheers!